{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 7.6 卷积网络分类过程可视化" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7.6.1 导入库" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "网络结构由network.py提供[network.py](network.py) \n", "第一个隐层为含有三个节点的全连接层 \n", "第二个隐层为含有两个1x2卷积的卷积层 \n", "第三个隐层为池化层(最大池化)\n", "![image.png](IMG75/1.png)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import network\n", "import matplotlib.pyplot as plt\n", "from matplotlib.colors import ListedColormap\n", "from matplotlib import cm,colors\n", "from mpl_toolkits.mplot3d import Axes3D\n", "import numpy as np\n", "from sklearn import datasets\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import StandardScaler\n", "plt.rcParams['font.sans-serif'] = ['SimHei']\n", "plt.rcParams['axes.unicode_minus'] = False\n", "np.random.seed(100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7.6.2 定义各类激活函数" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "activation = 'relu'\n", "if activation=='relu':\n", " activation_fn = network.relu_activation\n", "elif activation == 'sigmoid':\n", " activation_fn = network.sigmoid_activation\n", "elif activation == 'tanh':\n", " activation_fn = network.tanh_activation\n", "else:\n", " print(activation+' function not implemented')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7.6.3 导入数据开始训练" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "根据需要设定合适的参数进行训练,net.SGD()函数参数如下:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "training_data #训练数据

\n", "epochs #训练次数

\n", "mini_batch_size #batch大小

\n", "eta #学习率

\n", "lmbda = 0.0 #正则化系数

\n", "evaluation_data=None #验证数据

\n", "monitor_evaluation_cost=False #监测验证损失

\n", "monitor_evaluation_accuracy=True #监测验证精度

\n", "monitor_training_cost=True #监测训练损失

\n", "monitor_training_accuracy=True #监测训练精度

\n", "early_stopping_n = 0 #早停阈值

\n", "verbose = 0 # 是否开启冗余输出,开启之后才能显示上述监测内容

\n", "save_loss=False # 保存损失

\n", "save_delta = False # 保存误差

\n", "save_grad = False # 保存梯度

\n", "save_weights = False # 保存训练过程中的权重

\n", "save_Pl_Pa = False #保存各层偏导

" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": true }, "outputs": [], "source": [ "X, y = datasets.make_circles(n_samples=2000, factor=0.3, noise=.1,random_state=123)\n", "X, X_test, y, y_test = train_test_split(X, y, test_size=0.33)\n", "c,r = np.mgrid[[slice(X.min()- .2,X.max() + .2,50j)]*2]\n", "p = np.c_[c.flat,r.flat]\n", "#归一化\n", "ss = StandardScaler().fit(X)\n", "X = ss.transform(X)\n", "p_0 = ss.transform(p)\n", "X_test = ss.transform(X_test)\n", "p = list(np.expand_dims(p_0,2))\n", "#调整数据数据\n", "training_data = list([[np.expand_dims(feature,axis=1),label] for feature,label in zip(X,y)])\n", "test_data = list([[np.expand_dims(feature,axis=1),label] for feature,label in zip(X_test,y_test)])\n", "#\"\"\"全连接与卷积输入如[2,3,[3,2],1],其中的[3,2]代表卷积核为1*2,个数为卷积核数量为3\"\"\"\n", "net = network.Network([2,3,[2,2],1],activation_fn=activation_fn,cost=network.BinaryLogCost,layers_type=['FC','C','FC'])\n", "#是否已经训练且保存中间参数\n", "have_trained = False\n", "if have_trained:\n", " #如果已经训练了就直接加载\n", " weights_log = np.load('log/weights_log.npy',allow_pickle=True)\n", " bias_log = np.load('log/bias_log.npy',allow_pickle=True)\n", " net.set_weights(weights_log[800],bias_log[800])\n", "else:\n", " #否则重新训练\n", " net.default_weight_initializer()\n", " _ = net.SGD(training_data, 2000, len(training_data), 0.08, evaluation_data=test_data,verbose=1,\n", " save_Pl_Pa=True,\n", " save_weights=True,\n", " save_grad=True,\n", " save_delta=True,\n", " save_loss=True,\n", " monitor_evaluation_accuracy=True,\n", " monitor_training_accuracy=True,\n", " monitor_training_cost=True)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7.6.4 可视化实验数据及实验结果" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "scrolled": false }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAegAAADPCAYAAAA+jkI2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOydd3hc1bX2f2vUe++yJNuyJfcmd2MbgzEGbCBACBAgnZQLKTf3SyGFBBICCUlu6g1pJLkhIQkXCL3bYIxt3LssF9mWrN57mVnfH2tGXe5FyOd9nnk05Zx99ozO3mvvtd71LlFVHDhw4MCBAwdDC64L3QEHDhw4cODAQX84BtqBAwcOHDgYgnAMtAMHDhw4cDAE4RhoBw4cOHDgYAjCMdAOHDhw4MDBEIRjoB04cODAgYMhCMdAX2CIyJdF5MsXuh8ngojcJyL3Xeh+OHAwXCEij4nIRy50PxwMHTgG+jQgItEi8oWz0Zaq/khVf3Q22nLgYLjjbI29szmGHTg4V3AM9OkhGnAGtwMH5x9na+w5Y9jBkIdjoE8RIvI48B4wQkRKReSlHp+tEpEbReRpEXmjx/ufFpEjIlIsIl/p014v17GILPa284iIVIrIWyIScoI+3SUiR0WkXEQeON51vW0/KSIlIvKgiBwTkXu9/XhWRPZ4z1lxEr/FVSKyV0TK+nyHAfvjwMGZ4ARj76MictB7X3+yx/vf8d7jJSLy2RO1c5xr92unx/vF3jFzu/e9QhF5vMcYKxeRO7wu7H+IyCERyReROSdx3ZP+Xg6GIVTVeZziA8gCCgd4fxWwD1gJRHnfCwbeAVKBUKACCO9xzn3AfT1eLwbagP8AAoCtwPUn6E89MNF7rX8CEYNd19vHbwA/Al4DrgHe8PbjIBADTPEeH3qcfiYAB4AM7/V2AdMG68+F/p85j+HxGGjsAROAHUAskAQUe//GAu3eezoOePJ47RznmgO247333wDCvOOs1Pt+IfBh4F/A77xj+Q/AY8C7QBCwAtjb5zqPAR85k+/lPIbXw9lBn338QVX/rap1AKraCtwB3A78Axtc8Sdoowz4pap2ANuAqBMcvwb4HnAL8BlVbTjBdd8FGnv89d0HT6tqjapu8/Zh7HGuOQdIAzYABdgENWGw/pyg/w4cnAmWAKOA3dh4CQdygDogH/gJsBS48zTbH7AdVT2Cucn/E/grZjx9GGyM/U1V21T1WSBdRKIv4PdyMMThGOizj3U9X4jIaOAtoBobyEdPoo1DquqrYnIy1UxWAj/DBu9OEUk4wXXdff52dbfHcxfgOc41BXhTVZNVNRlIB54crD8n8R0cODhdCPDnPvfiOlV1AzOxnewiYIuIBJ5q44O1IyKXAE9hnqeP9DntZMaYcOIxds6+l4OhD8dAnx6qgDgRCfU+jhcjnoa5vP6AGaz0k2j/pEuMiUgosBPYDHwLW61nn+Z1rxORGBGZhrnOCo5z7DpgmojkeCeHV4ErjtMfBw7OBgYae28Ay0UkWUQisN3meBEZC7zufXwFSMbu68HaGRDHaWc25kH6G3DVSfb/VhEJFpHrsIV4/XGOPZ3v5WAYwf9Cd+D9CFVtEJGHsBisC5iLraIHwmvAFzGX8SvAIcx1XHiW+tIsIr/CYlUBwAvYpBExyHWPhy2YezoC+JiqthznuuUi8gng397j/6aqzwAM0h8HDs4YA409Vd0pIvdj7mR/4KequhVARN7G7n2AX6hqyWDtMMgYVtV9A7UjIv/C3MvHsDBSo9d4Hg8FGF+jEws/He+7nvL3cjC8IN2eVAcXM3wsbFW978L2xIGD4QkReQxYpaqPXeCuOHifwHFxO3DgwIEDB0MQzg7agQMHDhw4GIJwdtAOHDhw4MDBWYCIJHn5AYN9HuAVhHpHRD52ovYcA+3AgQMHDhycIUQkBvgTJlwzGO4GNqnqfOBGLzt/UDgG2oEDBw4cODhzuIGbMSXFwbAYY/yD6VTkHa/Bc55mFR8fr1lZWef6Mg4cnHds2rSpUlWHjAiLM9YcDFecj7EWmjVD3S2D29b28v27gNYebz2qqo/6Xvhy2kWk76k9EYZJtoKJSCUd59hzb6CzsrLYuHHjub6MAwfnHSJy+EL3oSecseZguOJ8jDVPawMZd/x80M/3/2h5q6oed8d7EmgEQjC51nDv60HhuLgdOHDgwIEDwOWSQR9nCZuABd7nUziBYJWjJObAgQMHDi56iICf31kzxIjIEmC8qv6ix9t/Al7w6riPB9Yfrw3HQDtw4MCBAwdwVnbKqrrY+/cNTE+952eHRWQptov+lrfwyaBwDPQQhjaUQ80RCAyD+FGIf9DZaVcVqg5CUxVEJCGxmWelXQdnHyISBfwd8AOagJtVtf3C9mpoQTtaobMVgiIQl9+5u059KdQWQXAExI1C/ALO/jUaK6ClHkKjkTCn/sX5xNneQQ8GVfVpt58QjoEeotCmavSNH0H5PgDksv+CUfPPTuMV+9Hnvg7uDjP+K77vGOmhi9uAH6vqqyLya+BKrECJA0DrStD1f4TKgzDlAzB2CRIQfPbaV0VE0IZy9JXvgccNoy8BtxtJGX/WrgOgtUXoy9+D+hKIGwmXfwWJTD6r13BwPAgu19CiZQ2t3jjoRnNVl3EG0PzXzlrTWn3YjDNAexPUOYVwhipU9Veq+qr3ZQJQfiH7M9SgB9+BwxugqRLWPgrVZ4fsq01VeDb/A33xPrRwPdpUC+4OJGcpbPkXvPQdtGjr6bWtina00E9muabItnHigqpD9jid9qsP43n7l3je/T1aV3ziExwA9tOfB5LYKcEx0EMVQZEQEtP9Om3qoIdqcw3aVHXSTfdalYsfhDuutKEOEZkLxKjquj7vf0pENorIxoqKigvUuwsId1vv157OkzpNO1rRxkq0vXngz49ugk2PQ/E29LWHEG2H7MXopr+BuqGzDV3za/Q4ebMDwdNYgW76O/rvr6Ob/4GnuQ71uNH6ErRiH4ycjyy8G/wCzLt1itDmGvTVH8DeV2Hns+g7v0U7Bq0a66AP/Pxk0MeFgOPiPgvQlnoo2402VSHJE5C4rDNuUyKT4Kr70JKdSGgMJA3sTtPSPeYKd3fA4i9C+tQTJcpD4ljkym+i1UeQ2Ew0Mo0Lc/s5OBmISCzwc+CGvp95hRIeBcjLy7voKt/I6IVo4XqLDU+6Dk4iVOOpPAQ7/w2F6yBtGsz9KBLeRwOjocdiRz3g8UDWXNj1Ari9FICAUDjFmLeU5aNbngC/QCQ4HF39U9Tlj2QvQsIT0eItaEstLL/P3Nynis52aCjrfl1bZO8FhJx6WxcZRIaei9sx0GcBWrgW1vyPPQ+OgpUPIlGpZ9yuxGYeNzbsaamDt35uZC9AX38YufFn0Hey6Yv6UvT1H4HHjbrbkSvuhcyZZ9xfB2cfIhII/BP4mqoOKWGUoQCJGQFX3w8drRASdcL4szbXIsVb0YI37Y3CtTByDmT3HjMyci665yVoa4AR01EROLweWfIldNtT0NGCLPg0EnSKu9z2Jvs7ZjG681moL7V+NVZAYg4UerNuOlvRRZ8/9YVzaDTMuBU2/i8gSN5tRmpzcFK4UDvlweAY6LOBou3dz1vroLUBok6tCR8ZZfDPPdBSBy5/8A+0gVx3rM9R4n2c4Fqt9ci0m8DdgbY1ohUFyGkYaG1rhNI9aH0pkjweSRh9ym04OCE+DkwH7hWRe4Ffq+oTF7hPQwoSEgUhJzng3O1G9OoJ9aDNNRAQjHh3mhI/Cq57GNqa0Y5meP6bdqjLH1nxIMSkdx17MtDONmiuRRPGQMIYc18313Yf0FzTezdeWwzl+WjyOEROflcn/kEw4WpIm2ztRY84pfMvZvhi0EMJjoE+BWhLHVq4DsrykexLIHUy4vJDxiyyXTRA3Cg4hfQI9bjh2HZ0+zNo/Chk/PJ+7jb1uOHwBvSd30BINDL7I+ibP4aAEGTWHei2/zMCy+IvIOHxfdreaQSzhGzrc1AE+Pmjm/9hqSnxo2HuJ07vBynaau51QANC4NqHkJiM02vLwYBQ1V8Dv77Q/Rg2CI1Bo9Ng1AI4uhFSp6BB4bD9Kagrhbkf6+JoSGQK2t4EhRu6z/d0QlvDqRnn9iZ053Ow+QmITEYWfR5VDxKVir79KxBB5n4c9ZE1xYVkL0Lf/Ams+D5EJJ7SV5TAEEgce0rnODAMix30RZubWbwN1thcqftXIdc+DAnZkD4NWfEDaG+A6IzeRrKuBFrrITwOCYvv32bNUUut8HRC8VY0IBSZdmPvYxrKzSWtbmiptdxogI4WdMNfYNE9SOJYJCy293nVR9CXvmvnHV4PMSPQrf8C9SCz70TX/REqDyDqOa2fQ8vzu190tEBzHRraZG68oHAkMPS02nUwvKHuDqgqhI5miE4/v/m+1Ydh90swaaUtTkt2wssPQPZiaKlBC9ehLXUQGoOExaGb/w4RycjM29H3/gLhiRCZcmrXrCmCTX+z53XH0IJVuBbchSZkI4k59n50KjTXmYve3YHufQXam21b5+C8YDjFoC/K3Eyt75GOpB6LTwHiHwjJuf2PrypEX/iWGej40XD5/0Mi+hQv6WjpzTztcQ2tPIAeWANB4bDo87Dqx95Lu43VXbzVdtFRqRAQbHGswLBuw9jeaMYZjIF6+D2IzbKFwI5nYMxi2P8WBEf27ndLvaWtBIYgx5mMJGMmuut5+y0iU9DgCFj933B0s+Vsz7rDEVtw0B9HNqKvPQwojJgBi+5GQqLPqEmtLzUyVHiC7SAHO27/W3BsG5Iy3hjZPpTnWwy4pRbyX0cmrUTfeMTu7ZqjaEgMsvJBCI6GtkY86x6D6FRkxEwkLGbQ6wH9iWTeOLn4BaDBkdDZAp3tuMLj0JQJ6KqfgqcDueKrvbxpWlUI1YUQGmtEz7OY7+3A4DccXNyq+qseLy+a3EwZMQPd/rQZ1fjREJV23OO1ZIcZZ4DKAzbQ3Z3GzA4IhZTxEJUKoxfCgbcgIBTJXQaAp7ESXnnQDCVA9iKY/iHY97oxtRPGwLhlaHQ6BIaiW56EgjcgeRzM+Zjt4qNSIXUyHNuOjJiGbn8K6stg3DKbkFImIjmXG9HG1+eWOttZ719lC4Pl9yEJ2f2+m6ep2pihV34LaWtAE8YgNcXoYa87cP9qGDnvlNz9DoY/1ONGd78AeAnnRzdBUzWcgYHW0j3mKepogWk3w+RrB/feRCTauAlPtMXB0U32/ogZ0N4Cibnmvg6NM+PsQ3sDJOZCXbEtur2pSzrnY8iklQN8z04jrgWGQkwGsvBuWxDEZiC5S+2Y2iL01Yeg9iiMWw55t9hYW/kgeDwWW/e1V3MUff4b0GbFjxxi59mHyDAx0D4cLzcT+BRARsbwiUlKQjZc+0Noq4fwxF6u7AGPD4unO+9F0JAYePUHUHvU3p90LTLrDmTeJ9CJKxB3BxoYYlSvtkbUZ5z9AiA2E4kbhY6cj1QXohv+ZEa7ow38/KC+CMZdYYpK5fsgPN52r4u/AC21Fof2CZ9s+Qey7BswYnp/AknVQTPOAG2N6N5XbVfSc7KoPmyLh8ZyGH8VGjcSdr+IetzI7I9a39RjggsOHPSAuPzQ5PFwbIe9ERwFp8qE7gH1uM0N7cv13fKEsbL7pCipp9OyHZLHQ8Eq2PMyTLsJGXsZBISgEUlIWz368vfQtgYYfxVMvRG2/guCI5GcpehL9yM5l3dfC3qJCXVdq7EK3f5/FhLLXYbkLIExi5GMGeAf3LXz1QNrzDgD7H3ZDO6I6UjQAKzr5uou4wygpbtPi9jp4PgYNgb6Ys3NlJj0436uHrcNus4ONCEb5t8Fxdth/HKk+hDqG5AARVth+s02caz6CVp3DNKm4plxC0SlwJhLjbASm4mu/Z0Z7IhkmPZBc8FVFSLJuWjBKmN1F65HZn+0V9xKwmIhLBbd24e5GhzZzzhr2R5TLxJX9+4hIAh96X5Y+DnwEsB053PQYOkh7HrOSC87nrHPYrNg3JXWhwF23g4cSO4VaFg8NFUiWXP6h32OA1WPeaVcAUhQmBn8ntwOvwB79DzH3QEH1qBv/xKZfjNaud8+2PJPdOHduEbNQwDP5re7wlbsfgGu+g4y5lK0tc67Q29Fw+MhZQKU7ALxM4PdFyU7YNfz9nzd7yEuC0md1N9LEJ0Gkcm2AM7IQ8v3Gbs7cWz/jI7wBDu/xZjfkjr5pH8zByeH86XFfSo4XZKYk5s5GI5uNiUfddsOefrNyPjl6JGNJg3odTkDkHMZ2lhtK21fylTxViRrNpKUg064Gn35AWT8cnN1p09FksdDcLgpINWXGMEsZSJMuhYOroGIJAgIxtNUjSssFq08hFbsQ0YtQEt2QUM5TFqJhkT1S8jS/NegdI8RyArXm+iDqi04ao6a6zsiuc8E6JUmTMwxt3ldMSz5TyQi8awV93AwvCBhcV1u3lOBejqhcAP67u8sDrvoHiQ2A5l6A+o2gQ7Ju61/6KmhHH3r57bodPWe8iQovPt5eEK3x0tcSGAoEp0G+w9aQQ6Ava/A8u8g01y28x9Ap0A7WiBhDDJ6gbnN+37e3mSx8IJVFgaKH42+/kP7bNuTyMqHIH5U735GpcLV3zXCWWg0xDuL37MNQfAbYqS8091BX/S5mepx2yDu8Q/VjjZzt/mIWTuegZzL0cZKM8AH18CEq5GUiRCZhB5cCwfXWEpFz8Z9k0Zzta2Y/YPNAEamohsfBwSZ98luec+SnUj6NJh6k6VfhUTDqHno6IXo89+E9iZU/GDpV013u/ogUlcKEUloewuU70UbypERM9GGSmOST74e9QuA1T+DsZcZg7WxAtiOXP5Vc3M3lCG5S9Gd/4aMPDPQ024Gtxvd9yaEx0NSbq9J0IGD04GqB+pKLK1PPdBcjW78Kyz9ihmvS78IHvfAFabEZUQttwct2gIzbrOxlT4NjRvZvVBNnwaz7oCSXci4ZUaoBDOWkSlG4IxKRyISjitEJKlTTATo3d/ZG2HxcM0D3RK7Ffvhnd/Y8/J85JL/6B7/7o6uXXK/dmMyurxYDs4N/PyGVljudEliF3VuppbtNUMZGgPTP4j4VuwNZea+qzsGO581d5V/EJTlowfeRvJuNeH9xLHQUmOpT4COWw5jlhiRLHshmjjWJo3QWBA/0wWefD289pCvB+iOpyF1IuzzlhuNy0L3vgY5l9mEVFtskn8+5SJ1w4E1yNjFaPFmaGsw11/xNvS1H9ghadNg9HyoPozu+qUxxBfdY59VFXoNNOihdy2WF5WC7nvDdtkZs5D06WhQKPz7axa/BuTSL1qs3IGDHtC6Eqg9Yprz8aMtE2Kg49qbbSG7fzUy8Rq713xwd9hrwcI1g02ukcnI0q+ja39jxK3MmbDnRXj9YUidiC74DBKRhITGIFM+YFWxekCi02z32lJnamUnUOqT6FQ8O57qfqOp0sJYPgPdRxtb1Q1+gSaiEhZv4973WUudiZgEhZ+Q8+LgzDDsSGIXI7ShDH3xu5bDiVch6LL/gqpC2612NEP0CJj/aSR+JBKRiDaUQUWB7XjjR0P6DHjlge5GG0qtetXSr9rxtUV4SneDXxCy7F6LTQVHWhyq0UuYj0qDuGyI2AkjF6DB0RAzwgb/zmetb7GZlrfZWA4IkjAaLd0LZfvQ4u3Iyocs7uyFJI+D5hp013P2RkeLyRG6/JGJ16Ble20yHDkbYjJNCjFlIjJpBeLbbZTsMoUx3+9VuhsZwEA7E8/FC22osNKNtUUAyNKvodEj0EPvgH8gkjm7x26zAN7+hZ3X0WyEyvWPmWDPzA+fVP1nEYER0+Dah83FXboH3fOyfVi01eLJJ4iDS3jCiSV0ex6fNtUIlmBjN7RHKlbsyO6QUFSaha0W3WPhIVV090sw8Wqo3G9x72PbofIQLLu3V8aFg7MLwTHQQxraWm8ynUHhvVjLvdDZ0WWcAWissPzjY9u63689ioTHWSoUWDxq8RfRo5uQ+FHosW3GEN33hg3UiEQkYyYSlYKnZBccetfaS5lsu+1dz8Hu520i2/emTWKpk2xxMOUmyMhDAoPR5hxLtfJh+9PI8m9D6W7wD0b3vY5MuBpm3IwWboD2ZiR9Grrj34BabNnd0b2aB2PZNlejtUXI9Y/YMVEppqA29+P9f5+w+G53IIJkzOp3iKe2CCnebkUBCtfDZV92Jp6LCU2VXcYZQA+usScH3rbXpXth8eeN7dyz2lTlAXTqTchNvwI/fyQ0xnL22xshKBIJPn4oRbz5/to3u2CQuKN6JUFPZhHQD+nTkOX3macsblQvl7hEJlm4qaXWdLLFD137W5MJBhh/Nfr6w1DjJZROWgmVhyw90xkn5w4ijoEeqtCGCvTtX5r4R2IOXPrFgYulh8fDtA/Cln+AXwCSe4VNNkERvQgmBPYgnwQEo9EjYNuT6OH14O60ghqjFqAh0bhCu9mdUnu0ewdbcxSJH9m1I9X8N5CJV6NvPGICIeIy1nb9MSONxI9EAq9Cj7xnBjZ1Ilq6xyQFC9dB5mxzlxeuRy75HMSkQXCUCTC01KIRKVB3zHYpe16BsDgkIRvd+Dgy+Vq0sQxX1pyBf7/aIvsdQmIsN7r2qO0c4nrrc2tDBaz+uamQBUcaq/bYdmfiuZgQEm0LP59BSpkIGx/v/rxin7miA4LRqFRk9kdML7toGxJjMWAArS8zUY+yPTAiDxbcdUL3MwAJoy1klP8apE2B5In9DtGao+h7/2v9mHX7gFoAx4MEhkL64CViJTSma1etHW0W//amN0rMCHT3890Hl+2F6LSuBUZXH5uqvG73yIFVCh2cEpwd9FBG5X4zzmCup7L87phRD0hAMJo+tWtVreKCl78HWbOQuZ9Ay/ciCTlo8VaISkUFpKHCcpUX3QOVB5HYDHTVTy1WPXohntylxmyNSqVfsYvOHgqqUSkmVejbfagH/PzBFYC++n2LEc+6Exbeg9QXm7rSpsfhqu8iE1eiBau7quVoZyvS2gihcUiSqaDp7hdh4+PoiOkm3JA5C6oOIHM/hq7/s1XYiUrtpbetTVVoawOs/jlUHbBFw/JvI5n9d86AxR19EqGt9VZoY5BSmg6GJyQqBa76Dlqej4TGofGjjETpTdVj0nUQHGEFLNY/ZsQucSFLv4pE90hzLM834wymq115eZcbWjtajIzV1gAxWUh0jx1scCTMuAUmXmPKe30UuTw1R+GtX0L5Xmvr5SNw/SP9pXTP1u8REAQzb7Mxp240frQV1KgosAMyZiFxIy085oXWldguu+qQhdSu+NpZqaB3UUPAb5hIfQ4/+AfZY8JViH8wGho9eF2oiCQ0vgUOvYMERaJjl0BUmsWaqw+b+9jdbizQiv3o1n/aBLPky2hoDHpoXXda1YG3kOg0NP91m7SSxhsBq3S3DdLYTMicbQpIDWU2SH0uaP8gEz/Z+YylagH62sPIld9CVz1hBjwp1ya4kp2WsznvLrSlBvELhLK96Pan0IgkGLsECY6CiStsB75/NZKUA+3NFvPzoepwdz50yS5LKfN0IjNuQVvrjIDTUIYe3QIJo/ut+q0ureBTkpLodEjOOUv/RAfvF0hcVlfddAF06o2QMRNcLogdafnNjZVQtMVOUA+699XeC7++jG1Xj9dHNnUVciEqFa6+v5fsrPgHgn9/lTutOGCiIS3V3W+21oOn4wy+7Ykh4QldJS8F0CVfNgPd3oQeeQ/d+k9k2TctxQrMMFcdsue1R20xcgIDrfWl6K4XoKkCmXw94hTU6AVnBz2UEZ9tBvTtX1psdMylaGxWv1i01pfCu783JaSpN0D8SNjzkr0efUl33AgsnrvtSe+JHlPYSpsKIX2Mll+g7YQbK3ClTUYv/4qJ6rfUQuke2xlXHoCmSjQ+21zSJbtttd1SB21NPTrotuo4S75ssoQRibD2d8jk61BvoQ/iRqFzPmqscB+hq7kGrTpknoRpHzRZw7iR/dXAvBOEttRbbqlX2EE3Pm6iLIfX2U4cYNpNJqrSYyLVznarwHVsuwmwxI3CFXpudiYO3j+Q4AgT9mlrQBsrjK8Rm2WZEL5MhMQ+C7mkHJi4Eg5vsEyBxDFdH+mhtd1tZy9Gtz6Jtjcik65F4nuHXXpCKwvgyHvIpOvQDX+28TT/U72Y1ecDEpmENtd0LzLweriiU5HQWJMQ7YnA46uxeTparWDH/tXWVvF28woMFMa7SCE4MeghCwmJxFO6qzsHseBNyLm8V51ZrTxgsdmoVNvR7l9tq/war1aLiBWJqCpExl2JNlXY+c019nl4gpFGQqJg7KVQXmALgbgsiyE3VaHtTUhIFFp3zOK4qtan5mrwC7SdR/xotKYIXfUTGH8VMmq+GdfWephyvbG+97wE465EmmvR6DTTBfeh6iDSXGPCD1NvNNH+9pbuohlbn4Qb/ttIOAGhyFJv3nPSeDQ80TwLIr1FH1x+Vp7PV3AeTIhhwjUQEoU2VVtRkJrDVlErOt3SvlL6x/8cXDxQdwfUlxohK/9Vk+BMGAOpk9A3H0EW3Y16w02S0VvaUkJjLW952o0QGIr0uB8lI8+MdOokGw9HN9r1irfBdY8MmjkgEV7DuOclZPrNFh9PyB44v/pcIzCkm7gJEBZrG4DQWFPpm3+XEeuy5vYrL6kdrZbRERiO+AdYHLtn/fj2pt7hMwdeF7djoIcueqZCINAjN1PrS9EX7uuWAsy53FIzesYstv4Lrrof8l9Da46CepCpN6FHNhozfMp16JYnEb9ANDLVdtN1JeaeLtmJHngLCfkWjJgO8aOMHLZ/NUz+gE0+YTGoyw+KtqApE4wl2t5s/Z58XXd1nLd/BZ2tSOJYc1973FYxp8gbYw+JtpSVSz6Hrv2tsddHzuuuOxsSiQSFmsve7UaTxkFTFVK620RNErIheQKy6B4j6bg7jUTW1mgThU+fOGUi6vEY+/aNHyOjFyJxWWjuMtjxtLG9o49fcMTB8IV63HBwDbr6Fya845PHLNtjOf6d7ei2p5Fr7h/UQIqfP/hF9v8gc7aFehTY8Mfu91vqvOVfByFVJeYiV3zdjHryOEga28vwn1fEZJhXL/9Vm2s8nV1ufAkKN4XC3Cu6+TDtLeAfAE016Ma/mMRw7kA7sxsAACAASURBVDJTGdz7sm0a2hqgvtQWzuFOIZueEMDfMdBDF5I111zY5fuQyR+AmCzAm+vcUtdtnMFWozlLzRVVdciEQcZfCRUFSOpEtOBN200njoGsObh8BJMFd5nx3vBnI7lEpiDTP2ilGpur0aYqK5bhH4SmTEZErExkdBrqHwTPfMV2vhNXQt5tRjABiM1CKwqstq273Ziy4Qm4IpNg6gfwlBcgwVFGDvMLQnc+j6aM7662dWitTZKpk21H3lSNlOcbCzxhDBoeb3rbDd6c6mX3mssxcya0NaGb/g65SyFrHpI+Hfy9ixBPB7r9WSTvNnTNr8ylHpsF13wPCYv17lhqoWgzWnMUyZqLJDmxsYsCzTXomkeR2Xd0p/X5IC5ATebW5WeLSP/gQQVN+kKCwmyh294MuVeYTK167Ll/4KD8EgkMgcxZg5MczyNEBE3KsTSyI1uQzLxeRDHwFh9xd1gJz81PGD9k7KVWRhaseEjaFCv2cfAd+24pE9HodOQEbvGLDSKOgR7SkIhEmPdJ6OzoMnzaUotufdJcQpmzTf1LXEjuMnTvq2jZblj6NYtBH3oXaovQjDxY9i1cgd66rz2vERxp7GUfk7m+xFjQDeW2y+6RziH1RV0kLAWL3fpiwntfsfxIbz8lMMRcg1d83RYTcSONLdv13RIshtXeBKmTkLxb0PqyHh1zdRXJ0LW/tZX7u7+31wfXIJf+J9rgqyqq6OENJtjvF4REhMGkFWh5gakw1RahbY2IgPqHIulT0Ip93fHu6kKkvcmEUcBSz7zxcd39Ilz3Qyft6n0MbW8xoxIQaobS935nu6VW+QcjwRHGu0iZYLtVVci9wsZQ8gRInWI5+tHpSMEqdMs/bGE3+87j1ijvCwkMxROeiMy41e7lwFBLcXqfQEKikbGXodmLB8/Hri0yLW/1WL3okGjLQKm3gjYqAu/+rsvFrbXFyGX/Zc9b682FHhJ9evnewwi2gz7DNkR+D4wHnlfVBwb4PAb4K5AIbFLVu47XnmOg+0DE1WX0AIsTe5W5GLPEbuzwBNsxVuyzQfHOb2z3WfiuiRLk3YYE9i+mrg3laNFmqwXd85qhsWZYQ2N6p5G01ptby3d+U7WRQVrarZZ0QO/C9BIYMmjupYREw9yPWTw7INRSRhorLJWlPB+ZcBW69f8snu7yh85WetXD9QswjXBfPdqUibbkDI40zWFxIZf9lzG7N/6v9TcsHhZ+zqoI5d3Wq/QmgGfnc6YhXrG/+zqdrSYW4+B9CW2uQTf+zQRz0ibD/LvMS9LebC7sLf+0zITFXzAJzdkfsTrJh9baAjN7IWQvwuWLqVbsR1f/zJ7Xl6IxmUjeLafUJ0mfbgI67nbkfbpzPK7xdLf3HqttDZA03hb9uUuRoHDzDPpQcwQ620wV8c2fQGMFMudj6OiFFq++WCHgfwbVrETkA4Cfqs4VkT+IyBhVLehz2O3AX1X1ryLyuIjkqerGwdoc9gZa3R1mPE5xdagtdaaG1bVrxDvpTEGj0pDshWjcKCRxDNpUYzGi638MuEA8eNqbkdoiS42KTEZjMmHzE7DvdTRtipWZPLLJikykTjQD2hdRqRCTaUbTPwgZOddqL6sHSZsMLpdpGvsHnVSOpgSFdxfiwJvaMfPDaNVhy9+edQfaWm/CJv6BEJUOdUUQEAoRCcjy+9DKA0awScw1cRJfCpZ60P2reys/NVVaXWtV20FP+yDUFiEj56Eb/mKEsczZpl9e8KYtRrzKag6GLrS+DN39AtSXIlOuQ5LGdX9YeQDyX7HnRzdbtkFEkuXvb/yrvV9RgO5fZQvZmHQYeylac9gMR9oU6Fk6prOt98U7mozr0NZoxLC+aXwDQPwDTJxkuCIqzeLMO54xrfCJK4yQOuNDEBRhnrGpN9jiCGwcBoWj7/7WdtyAvvULY7d7U98uRpxENat4EelpTB/1llb2YTHwD+/zV4AFQF8DXQVMFJFoYARwlONg2BpoVTXi1Xv/CxEJMOPWARP5teaIVcmJSEQ621BXgLGZtz8DzZVm0EbNh8PvQepkM8qlu4wcBahfoOUAv/htmPdJRLEqO+GJMGKa5RC7/JFrHujWvfaVl7z6flw90hzU3WGTV+0xc/EmZFust6HUFL9iM5GUCXZsezO69xVY90cIS4Arv4EMUPruhCjPh+e/aW2KC1nxIJKUY/Vxl38LaSiH0Cgk2lzOPhe8drZB8Q5jlPr0wTtaLX7tK6cZPxr1uJH5n0Kbq20RMmo+uu1pI61lzjKG99pHTS0qItFc844295CGbn/aik2AydZe/+PusdU3LQ+8C7fW3m9KjwVzUKSxpQNCoKMFCU+06lVF24xgOW65XS8iCcYsQdf8j1WGS5kIC+826cyLGW2NMGoBMnqhETx9amrBEd3HTLrOagC4/CA2w2LXPQuPODgZklilquYd5/MwoNj7vBqr+NgXa4CrgXuAPd7jBsWwNdDUl6Av3W/un/J8FJfJd/YsD1lzBH32XsiaA2GxRrIIDEOWfAltqjQjUrjOajhPWmkG5Y0foWk9iqW72+3RUoeIq7scXn0JGhhq6VOV+y2XecLVsPa3dl7qFCQoonefKwqsPygqfsjKHyCJY/rtKLX6sE2S6kFm3Ylu+DO652Vk/qdO/XfyVqiyhq2MH3jd6cXb0KZKJHN2//PcHVDwprn281+xRciYS1EEmXUn+PmjiTmw5xV032vWZtxI0yVPzkVdgoyYbguohjJzk49bjmsIkHMcDA71uE0Yw4eOVgtL+BA/GqbfAk0VEJGCRibDs1/zjqFrTX8+NhNJyMbz2sMmnpM22WLVne1oSKQtkGuPWUENT6c3Y+DzaNoUpPJAt3Z3yU5jfF/EBlprjlp2SXMVGpmCXPmNAY+ToDBI9ioGNtegRVuNR1NbBI2VyJyPnlDoZLhDztDFDTQCvrhjODBQRPvbwKdVtV5EvgR8FHh0gOOA4Wyg3R29maFNVZZu5NfjK9eXQlsDkj61q2A67U1m/EYvNAGQpHGw+e+QlAvVR0ykP26k1VdWt+U0i3h3DtI7FtTZarFbl78RN4q2InM+BmFxaPL4XgSarv743Hvqtp1pD/EFAG2uRV97qJvwkVQOWbNOKFQwKGIzrd50Z6u5w7yDVPe+Cpv/Zs93vwjXPtxL1ECCwiHvFpuw3W5orkVfeRCmXG+ehoAQwNUllwhA1SFzefsIYQWrkVm3dyuV9f09HAw5iMvP6o6X59sYG7/cvEU+BEdYQZiDb9vEnzQWReDYdiOILfkSeDzoyw8AihauQ6592CqxHVoLq5+xhV3u0m7+Reku1OWPZC+0HWBPuC6OmKl2tEHxVrR4G5I2BdKmGpG18oBVwgMLyVUdNpf3YO143FYcZ/tTNi9NvRGyFxmz3Vsc5GLGGbK4N2Fu7XXAFCB/gGNigEkisg6YDbx23P6cSW+GNMITYcatpkXtH4zk3Wo5kz0RFmcGVNVuVt+EEBBqQvrl+RYTW/GguW/VjSblosU7kMu/0pXOpKW7kLkftzSGGbeaYk9IFDL1RmiqgchEM/qH1pr5dfkjN/4M+1/1QHR6dz8Cgk17uy/c7dCTfd1YDiPnWQrGaUDiR8PKH9ggD080oX71QOmu7oNa67vIYapqO6iONjQx14p7FG3uPrZsH5o8Hv79FTP2I+dZfjhARp6xRn3wLXAiki3nc+yS0/oODs4z0iZZZbPONhMQ6cFroO6YLSA9ncYuDgyFUQvg4Nu24A2NQ6oLIe82tOANW2i2NUF1Ibrqv62N6kKISYc5H4N1fzCvVt6t5pZNyIZpNxsfZMSMrl3hsEfFPvTVBwHQ3S8gV98PqZO6xYXA5o+gcCsLG5VmTPm+aG/pqkOPp9MWTkHhsPVJNDYL5n/yotX0tnrQZ9TE08DbIpIKLAc+JCIPqGpPt8aDwB+BTOBd4G/Ha3DYGmgJDIGJK8x97RfQK+XIBw0IRS7/CuoKMAbyxschLBZJmWB5k2BGuqnKXNviQpb8p008W/4Jl33Z8oyTcqC+xPILQ+OQ7EtM9cur/avuDmjqEWpQDyCWtqQK4fG2M0nIRq59CBoqIDLJBPL7IiQaZt3uJWcJMuNWdOQCJDCo/7En+1vFZfUih4i4YMJV6LEdgEL69G5hh+Lt6CsP2O5p3HJ0yvWmoXzkPevPxKvQnc/BpGuRwDA0KQeJGwXudrSj1URa/IO6JncNjECue9iIbv4n/g7q7rgwqk4OuiDi6tJj7wePu1fmAW2NxtietAINijCS5NZ/GXFz1p1oyU4Tq6kv6d1OawMy5QbLZfYLtBRIvGmK026ECVdBQMhJ50W/7+FTOOz7OjEHWfx5tGQPkjoBffE+m1/GLYeZt/VePIGpk2UvhE1/BzCy65r/sc+Ka9CCVUjerQN2QRvK0f1vQUMZkrt02Gl5n6lQiddtvRhYCjysqqXAtj7HbAAmnGybw9ZAg9dIxw48kWjNEXjxuxZrDo2xik8rH0T3r0YrD9Dlas65wsRHZnjzhmuOolv+gcy83XaaYAbDO2EJQJ+6tOIXAHM/bhWn2pqQxV+AhlJvjrMbWfKfaNZsm/jiR/cTI+jVln8gjFtmBBlxQXQ6rnMxSY2YYa7HjmaITkdCos09tu1f3dKDe160cpsLPgO1K4zkE5dl5TR3/BtNmQBrf2txLgSZ8xHLqV76NdMVb6yAIxtOavfvk1/k6GY0dxkyar79fx2cd6h6vOUgQ3pxOgDLv53zcdv5BoUjM29HwmJR/yCkocyMMxjrv+BNWHYvEh6P+gXA2CUWow6LR0YtMBduz7RDL8QvoJcE70WBmEz7zi119jfGCKESFAZjLoWR89Hn7u0Ose150cIPfQy0uPzMeMePMW9c39BYe7MRQBHLYHH5mZdExEJdO/4NYxahh99DgyJwDeTle59CkDMWKlHVGrqZ3GeMYW2gj4uyfCscD6aVXXXImNOhMWh7M5L3YVPDShoPm/9mdZTjR8OoeTa5bPknjJxnu2M44a5OEsfAdY+Ax436+cMzX+lKIdFVP0Vu/IWxzU8CEhBiWrznEOIX0C/+LS4/q2t9zKvrHRBsOeO+spFhsdDRhoTFoZX7kcyZXuMMoGjZPogbaav8wDBk1u2QPsMELMr3obVFSFSKCfkHRRh5yOWHNtcgjRWWpgZW5ScqBVJOeiH6voaIJAH/UtVLLnRftKnG6pUf2WgGNeeyXrs08Q+yBWRGnvE1whPQ2iJ09S8sR98r1ANYjeMQb5hHXDDpOmT8VaYHEObIUPaExGZYqK2pyuq093VD+/l7q+d5s3qCImx8DtRWSBRkzAAsG4TJ18GOZ60QR0QCVBWaOuI7/2Pei2X3oikTrVTu7Dut8l7DOxAUho67sl+5zvctHC3u8w9trTd3Wo9JRNuabJfXE34B6KF30fjRSGA4dDSjYQlIU6UZZzBN6coDliISHoe01KKr/9sml7kfH9gl3QNducptDWjPm9o/uLem9xCGTLrWXNT1JcjkawFBn/+mfSdAFn3eNIyDIsx9HxTRLZGalGO5mKGxJvZSvM124KW70ectTKPih8y+w0IM45ajJTuQccvRlpreHeloOa/f+0LBqzz0JyyF48KjptAKsbQ3wfo/GsmwjziO+Af24k/orheMLFhz2HLtS3ZCaCwyfjni52/ekXf/AAffRiOSkCvuNX6Ig16QqNRBmdYiLph6IxoWC03VyLgru8ICPaHqMbJre5PtjMPi0NBYWPx52zzsfBaJyYR3fmMnuNtNUfDq78KsO2xx5isOtP6xrmIiwwGOFvd5hh7bgb79K6vzvPBuJGE06uk0t3ZDiU0WlQeR5HHozmetBvPIeejIuVB5ECKq+4nqi38QmjgWZn8UfeOHXWlK+uZPTF96IGJGH0hQBCz+PPrWr8DTgSz4zPtmxyCRScjsO7tea8nuXhrlemwHrrGXWm3rYzvMfV9bZBNBWLyR7iISzWOROhncHWhdqS1y/ALMq9DhTdupL4GgCHTXs0jerVY6s6HcUnZis87zN79gcAM3A89cyE6ou8N0BQ6usUVaxT7bRfcVEhn4ZPvb0YK++3vkAz/pLeVac8RIZGApd4fX245xCKO908PeknrqmzsYlRhOasy5Cbdoa6PxYNrqrSTucSRwJTIJmXEClbWSXeiL3zGeQPp0WPR5JCnXCHqN5TDlBjQ8wZuT7hUdGjkf3vtfU/zruwkZWvbsjOBocZ9HaEOFpf14bzLd+xr4B5g79dmvI9Nusphy1myr++rLBz68wXKXtz9l5839BMy4BfJfh6QcSxmJSLYbuKckZR9ZzhNB4kfDNfcD+r6UHuxCeLyt6r1pXzJyjv2NH4XEj7JjksdZGMEv0MoArv6ZhQmKtphnIyIBmflhtK0BCY03opH4ISNmoJseh5gR6KF1MPZyJG0qRCYOrLw2DKGq9UD/WK8XIvIp4FMAGRnn0KhVHTJdAfWYp2T2R1G3G7z/Y22pMz7FAIp2MuFqKxlZd8wIjuF9Qjl+fciBJ6EOdqGxtqCST/xuIx6FmSNj+Nkd00iKOvuuXi1ca9XpwORKV3wPiTj9vG/Nf83mqYhEG4u7/m0E1jqvvsbmvyMZM+DKb6Lr/mBqbREJqDflUsYsRhPGWEpo3m0Q3XvBoHXHoOqQxbYTx7yv5jaBEymJnXcMWwMNHvB4yUxjLwPxoP+6B3wutKoDVvowOsPKPua/aseOmA5lu7ub2fMSrHzQ4m315UhTOUz9gBmlSz5nNZkRZMFnjGF9CpC+Rdffh5CIRFj2TdsFBUf2I7hpe4vJQm78q1Xgik6DaTdZbHnT36G5FioPor4FUUgMLP0qcvV30F0vQfJ4ZOoNtkuPzhiQjX8xwys1+ChAXl7eWZWG0uYaW7gGhtkCtEeOv6LIpV9EQiLR8n3o6z+y3fTieyB9eq8FhcRkwFXfBXebFWXoy9eIH4ksvNvY/8njTTt7iOOf64vweH/t9w7VcKy25ZwYaA6/1/28qdJIYmdgoInPhv2rkWk3mx5BZHJ/UmpHm6Wp5iw1xbYeGSi64c+w7Jvm4QiJ6lWKUxsr0Je/123sF96N5Fx2+n097xBcjoE+TwiLRy79ErrjWcheBLtfsPcbytDD6+ymO7zebs4Fn0WSxwOgUandebsAE65GAsPNLR2eQE+GvI6a271L9DIdhzu0tcGU0TydVhgkLM6MptdwalsjWrTFSkemTjIW6Ht/gdiR0N6Ivv1LOy4mwwQv/AIsnOBDSw2ibivGkZhzWjrqDs4c2lRt/6ujm8xbtPw+E8CoKzaCX+okM85tjeiBNVbisDwffe1h5Mafo+HxUFtkjP+IZCRk8F2x+AdBzmVGwPQPsnjqEER9SwcbD9VwuKKRvFExvLjdClBEhvgTHXpu0r1k9AL0iNdIR48w/sYZtTffctN9egu1RVYtK7EMGkpg4gp0w5+gsRy5/KtoxT6rMT9uuQnJpE2xgiMDheSaa7uNM8CBNfZ/fZ/A2UGfR4jLD0/yBFPaee0hiM1Cpn8I3fx3I2X5BdjqccoHYMNj3pxfzJ09+Xokd6ntHOJGDe5edPnbjvAigbo7rCLRZsuhZNQCWPDp3rmWx3aYUAVenfLl3wYEolMtluZDzRHjAKz+BTLjQ6bpDBCfbSU11ePkO19I1JeYcQYj5B1cgyz/FjRWQnBkVyxUm2uhfJ9VdsucDdmLATHVq9d+aOdO/gBMu/GEHiMJGBppcyU1LbR3uqlr6eSdfZVkxIcxNzuW/WVNPLHuKMU1Ldx9xWh+/dFp1Dd3Ehnsz2Chy8qGNtweJTEy6PQW8BkzTZTEW0f9THXqJTQWybkMT/6rkDjWsie2PAHLvm2a/y21FmeuKECP7USu/zG0NqBh8ci0m8zlPRhrOyQaIlO6c9pHzj2jvp53DKcY9FBK/RgMUn2oO++ydBealGtGJX0q7HwOZt2JtLeacZ5yPeIfDIHhaPEWiEwZEkXbhxTam2Hf692vD66BmR/ulWupPXfD7nZUQS79ohX2yJwNNV4d55RJqKfTcqMjkpFLPgcuf8s+f+E7sOSLaEae6Zt3tJkLHSBmxPBJ6zgFqOri83atpirbYfnkbMHGQ0RSf/dqeX63nGvhu0YKdLdbmdaJK4xPsO1JGLN4UE2CoYLCiiaKqptZvbeCyJAAfrfqEA2txiv55Z3TWFtQxas7y0iJDuZAWROPvLgPVbhhZhpZif1jrdsO13L3X7bQ0u7moQ9N5tJxCadspCUw1BTDzjIkPAmNG42MmGFzXuku8JaJZdxy+3/70rmienPBtLbYQh4RCUhY94JBIhJg2TfMIxYUBgnvLyETgeHh4h5KqR/q6TTyiccDUam9lYX6VmsJCIbc5VYEw90Ou55Hp38QptyEhEZbkXlPp92w7U0XjKDY3uFmdX4FT6wrYt6YOFZOTyU+4vSVwqob22jt8BAfHkhgwBm4iwNCjPm592V7nTQO+uyKZMQ0iyd7Om2Qh8dCyjgkbSqqbqvG1VqPejzw6g/QMZdB5wb00FprwDuR6xuPIDf+Ag2NtmIbviIjcz8OaVMtXtnZiky+3pTQHJwVqM8DEhpn6nr7V1mBk6wBCqbgzY3veX5YvKXo+CqapU+DrHkwxBW/dhXXcfuvN1Db3MHkjCg+PDezyzgD7C9rpLLBGOt5I2N4amNx1/Ty5HvF3D4/k8bWTsKDbUptaO3ga//cQVG1pQN+7k+beeX/LWRE3BDhnaRMMOPf1oAGhps0rw91RTDlhgFry2vlAfT5b1maVvwYdNF/INFpXbFoiU57X3sVh4uLe2ikfqgHCjd0V5Ba8BkYu6TbNZqQbUn4u1+C+FFIYg569D0o2tKdy/dWJSz6D/TNnxoJQ1zIgs+iSTkX7HvtPlbPp/+4GVV4Y3c5iZFBXDPt9PRxC0obuOcvWzlc2cSXr8rhQ3NGEBp0ev928Q+0WrKpk2yBkzy+fz3epFyTK22pMwMd6SV1hUTagic0xtyiT38Z/AJh9Dx4+ftm7JNyjO0dP8rilyK2Ut/8BExcYYXn3Z3o2ke7xFK0dA9c+xAS2kfX3MEpQ1tqjWHvrbesa3+LXP+ILV4HOt5j2vSMWWJjKvdyIwr6yqqCpeZc+U3LnqjYP6RESOqaOzha3UxIgB8b9ldR22yk0u1H6ghZ7CInJYL8kgZcAlMyokmPDWH9gWrK69sYkxzOgfImAFKignl2SwmdHg/3XDGGmLD+i5GhVtnRJy0MQEstOiIPjmyw+W/iikG9h3p0ixlngMoCpHCDVQIcvdDqbr+PcRL1oM87TmumHjKpHy31lgrgY5eu/a2t2H26vUHh6MQVdiMW70AL11nJyIAQr8tUbSXZWGm50WBpJDVHcOVefu767UVjawd1LZ1EhfgTHtx9c9e3dPYa0MdqTl+U47G3C8kvsXSwB57ZQ97IGCZn9J5wqxraqGhoIyo0gJTo48cBJTwOwhcM/rlPrrQPtPowWl6AhERZmkbWHCQiydzX0z9oBUD2vASJ4yBlIpI+3SQg2xotVr3ln2hDGcy83Vv1y4umSlMrC450yGRnCnH1rhbl6eh2cfeB1pdamlxnG5owGpm00khk6kZzl8Gu5+zAccug9hgcfc+KyYTFw5XfPL3a5WcRdc0d/PjFfP7yzhEmpkXw9WvH88MPTWb9gSpGxIUSEuDH/TeMp6nNTUxYILmpEfzy1f18fPFI0qJDaGzrJD48iIa2TlZMTeFzf95CW4eHKyclMzs7jojgAL5/0yTu/vMWmts7+eEtk0mPHRox9r6QkGhY8Gmo6yHXO9ixEUndHhNxWVnZt35hdeIv8P/0TCEXi5LYuUz96AW/AFMc8hnXkGh7rwek6hBastuKmKsb7WyFos2QuwzyX0HSJkNznbl0XC44uNZutnOM0toWfvj8Pp7fVsLSCUl8bWVul9hBdlI407Oi2VxYS2xYIJfknJwE6EDw76NQ1ndRVVLbwlef2M7b+VWMiA3h95/MIzvpxGIrpwKtL7WatS01NrgXfBYZuxh9+fvQXI0s/A90k7eoS/EWSJ+Cij+CLbI8rQ3Q4K3gtedly2F/+9eAwsRrYP2fYfHdgxdwcHBSkOBIuPSLJlrhcSOL7hl0t6tHNkHlftPTBjQuC7ny2+bJmHaTSX2KoP4hSPFWM85gC6r9q5FZd5yvrzUgiqqb+cs7RxibHM7lk5L58K/XExzgxwM3TuS+p3bR4fbw57tm0d7pobXDTUltKwtzEyiva0MFXt1URkNLJx+aM4LfvHGQtg7bJAT4d4+3qZnRPPWFeXR6lKTTJYmdB6gvf32AHPZ+SJsE8++yCmSxGeiBt73ldofmdztVDIsd9FCBBIXBws9ZPm1nm5V6LM83I5Aw1kT6XQHmwvGlWaVOsupR6VMgLAaCIu3c7U9aIYu5n0DDE895/Hn70Tqe2mQpCc9vK+GqqcldBjo1JoRf3jmdktpWosMCyIo/vVD/0apmFubGc0lOPMdqW0iLDmFMUu+28ksaeDvf6skerW7hnX1VZ91A01IHPaU6W+uhbB80e/Mrm/vKeLZC0ji0vADqjiHR6aiPHdpYjsZkIpd8xmpQH9sOlQX9pVsdnBYkMcfKj6qaZvNgUI+xt32oKjTXZ2iMneeLX1Ye6F2DHYaEEElIoB/BAS6WT0nhZy8X4FFobnfzmzcPMn9sPHFhgdz3f7sICfTns5eP5vZfb6CopoW8rBhmjIohwM/F3DGx5I2KYc2+SkbEhnDXpaOIDg3gnX2VxIUHkpsaeUbckXMNba5DC143Rbicy2Hk3BMy6SUkGtKnWQWsLf+A0QuMGBb5/tcncNKszjJUPdDZjoxaYNrOBavQXc/ah2Mvg3mfMKWr0h4xsZJdkPdhq6R0YI2lhWx63IwIoGsfRa7/yTnve9/VdN/bIikq+JSFD6ob2zhQ3kRIoB8Rwf58+o+byS9pINDPxdevzeWPk7Y00AAAIABJREFUbx1ifHokKYHd//bQwN63QGz4OSDzhMXa7tbLxJboNJPs9LKEteYojL8KCt401bHYTHOdvvRdI5uJy3Latz4J45ebSILLD33vfmitg1l3DqpR7ODU0Y9XgE8prNOERlx+kDrRaohv9+a9Zs6C4AEMekwG2lJvpSUL3jS5ynOYfnOkqpmnNxVT09jOzXNGkJtq3+VgeSP5JQ3EhgUyaUQUoxLD+cMnZ7K/rJHgAD+a282VHx7kT6C/kB4Xwt/WHeUb145jw4Fqirxhpo2FNdw4O43JI6II8ncRHuTHwx+aTEu7m7qWDj722/corGwmOMDFox+fQV5mDMGnyfk45yjbDRv+DICW7kbCE+3/egJo8VYo3mov9r2BjF44bFIih5WL+3ymfgyIyoPos18zMQS/QItV+j479A7MuAUJT0THLDbpzsAwk6eLH20Gedm9XaXwuuDyOy+M0ykZUdw2L4PntpawdGISUzO748LVje1U1LcSERJw0hq/RVVNrM6vpL6lkw0HqrhhZnpX7Lnd7WFXUT2Hq1ooKG0kJTqEprZOGlo7GZscxkMfmsTja49wydh4Zo86MyGEgSDhCbD0a0bMC4ow1+f6x5B5n7CUnqh0L+s7yWJgTdXm1fBJp6oH3O3Iyu93r/ATsuH6R+x/HxZ7UrWkHZwetPKA5TS3NSCXfBbNmoMrbiQe/yATlHF3mIt7AB168QswZn/qRMi9AgkI6qU+dTbR0enhpy/t4+lNJjv70o5Snvr8PDrcyp2PbqCivp3b52fS6VEmpUcxJzuOzNhgEiOn8NOXCogI8efLV+Xwxq4yOt3Krz8yjc2FtUSE9DY+IYH+fO5PW3AJfPsDE7hueiox4YFsLKymsNKkhVs7PLxbUIUqTMuIpryhjdBAP5JPwPE4n1BfVTEffLLIjRU2BoOjkKjkAc7sY8SG2K7zdCEyTEhiQwZ1x7prE7vbvWQxARQy56D+wUjxFqtLe+mXICAUXfMrm+znfsJuxIAQe/7WL6CtHpl/lxmKc4zEyGC+vjKXzy3NJiokgJBAI+eU17fy7Sd38fIOy7f84ydnMjYlgo5ODwVlDVQ3tpNf0kBabAjzx8QTERJAQ2sHP391//9n77yj46qu7/+50zVFvfduFVty7+CKCy5gA4bQCS1AIEDgS2gBAiEkBAghBAKhEyD0bmO6Dbg3Wbaai3rvMyNNv78/ropljAEXYvix1/Jao9GbN8+jue/cc84+e/PKepXNXDYrHb9fYtRrBnpjmTFW8hKCabW72VHbxbNfVLGyuImTRsdzxexMFo+Kx3g4I1jfgn61MelzIzsbIH8RsqkE0CAMFqVe1H/stKtUZqw1qL+r0Kq5yqYyZPyIATLY4Yo2/Ixvh/R7lNOUXRHz1PjbQ8oq0hYD7dXIrx6HoFDk9KsQ32BiIrT6o55luX0BdtYNBp2mLjfrd7dj1Gupa3dx68m5PPHZXp74fC+nT0jk7Mkpak05vVw1J5Ner5/bXttBad/GdnpuFGdOTGJlcRPnTEmhuLaLk8bE88JXagIkIOGxT/YwKTOc0no7WiHQawVev0oT0qIsrN/djtPlo7zRQa/Hx0ljEgay+n509Xhp7nZhNem+laR5JCBlQLWXYnIGK1vRORCeqvgiK+9WzwWFwewblKb2PuRBkTgSmTxOmQvlzoOI9KN+zT8Efi5xH2nYYhSTUAbUTTw0QQXY0ASkJQLRVYcs+QBqNiEzjoe2PQN9T7n6nzBiMbL8U8TECxAL7gC/7+B9tyOMIIOOoL4Ss8fvx6DVUtHo4IPtihDV0Oniw+ImMmOsrChq5Jr/bCUg4dKZ6by5qZ4gvZZpudG0drsHgjPAO1sa+PvZMdx16nA2V3aQGx9MUngQFzy+EYCEMBOLRyfQ1ePl2S+qOG5YJLPyj/6mRHbVK+u67gZEzhykLVZlyX7P0OO6G6H8U8TsG5QWdMCHXPcsYvgiRQo8iKPPzzgKGHLT2udxdyPy43sV07unHbnuGZh7y/+MTW816bhidiZX/2crUsJJY+J5bWMdhcmh5CXYqGh0UN+pnNL+u66WhPAg7l9ewaSsCCIsBjJirJQ3DhrglDXY2VjZycSsCAIBGJUSQk17LzVtg1MVcaEmfH5JeaMdq1HHzSflUlJvJzXSjJQwJi2M3zy3FbvLx/DEYDJirEMCdLvDw73vlfLfdbXEhhh58uJxXwvgRxIy4Ieq9Soh0QchZv5WKSuaQxHmMGTlukFRoN4OZO1m9eePyRk4h7DFwIxrlEqc0TZUe+JHjp+EUMkxg6gMxKK7oasB9EHILx8DexNi8iWw5glke6WSm8ua0eeQtA+juf/xrs8hb77Su9UaIGMqIvhAZZ2jg6YuF899WcWaijbOPS6FhP1K2pE2Ix1OD39+t3RAnP+Jz/byq1kZ1Heom43bF2BYnJWyBgcA+QnB7Gyw84+VFQgheGNjHb8/OW/gnHUdLoz6wc9CSvAHJLXtqsSVFG5GcxR6MbL4nQH5SLn+WcT0q5EaLVJrgKgsZTZvi0ZYo5C2KKSzBdY+ORDAZdHrEJ39nQl80ueF5lJkR7Xy6o4e9vMo1veE0Bpg4i+Rn9wHrm5FzutfH1IOMdDA7/2fD/zOHRHDm1dPpq69l3e2NLC6rJWNezt44qKxbKocSkbUa9UacHv99Hj8rN3VxpKxCby2QW12F4+O56PiJho6e7lkRjqbKzuJDTVx/1mFPPl5JWajljMnJfPX98swG3QsHBXHRzsaKWlw4PcHGD0+kc9KWwYET4pru9FqBOUNdvQ6gccXYE+zk9QoCwtHxrKz3s6bm+r43VEM0Nib1d8y4AOPE7nm34iFdw22joxD2xTCZIPeLjWiaotG9GXLwmD+mkjRTwHHWAv6Rx6ghVapfgXHw/qn1CiO3qzmZdsr1TF71yDGnIksXYmYdpXKnH1uxMilyG1vQP4C5Kq/D0hQypYKmHHNUZGTlFKytaqTXU0OQi160iItbK/t4p8f7QZgS1Un7183hbtPG85La2sYlx7G+PQwatp7uGxWBg+urKDV7iExPAivz09Bssr2hYBr5w9j4952jDotbq8fjYALjk+jq8fLU6srMRkGA1NMiJGCxBCunZ+NUScYkRTCJzub+PUzWxAIHjx3JHOGxxz5sRC3c58PIwAhcWiistSPkRlKB9hoA59LMb19HuXl3Z9h22IVeWzXKlU9ico8eMBtKUe+d6s6v9AgFv1JiaH8jO8FEZkOi+9WTHlz2KCZRXCMWlNfPKLm0Cecj9ifsf0DwuP1U1zXTafTQ2KEmc19Adli1BJuMTBvRAxlDXYqGh38YmLSwBRFaX03/75wHNe8sJVIq4H7zyzAZNDy5sY6LEYdS8cm0OZwc9vrOwC4e1k+F0xLpd3hYUddNyX1dho6XXT2ePnltBSig4NIiTRjMeqobh/MtrUagVGnZd69qwkyaLlxUQ5/freUuFATp41PIirYRN7RDM7w9X6xGFw/ga4GaChGTLwQ2bAdItKRQaHwyX1qDepMsOjuQYOgnxgE36zt8b/CjztANxQja7eoMYHUCdBUqspt++/swlNg8kVKLaxwCVgikR2VkFCg/vWLKoAaC/G5lCzoEUZxbTdnPrIOtzeAUa/hlsW5JIYHcfXcLFxeP/6A5I2N9by1uZ7hiSHkJwTz6Cd7eGV9LWaDlruXjcAfCNDV4yXIoKWr10t1m5PoYCMOl49Op4d3tzZy2cx0XlxTzfaabqJsRu4/sxCjXsNTF49Fq9FgC9Jxw4tFlDc5+OXxqbQ7Pby/taGvdya5+eViksKCyEs8suV+UXCyWvg9HWokLiRx8Hf7zWGKsCRk9UY4/tfKE1qjR4w8Ffn+71WmJjSIOTcjY4YNNevYF/bmwccyAM62I/r/+f8J4gAMbaHVIzOPU0Qxre5/rua2qryVS5/chJSQF2/jyYvH0tXrIzbERGqUhe5eL3oNpEdb+KykhVPGJXLC8BisJh21HT0sKIzDYtLx1KpKblyUw6LR8QgE//xoN0vHDcpXJoVbuPTJTXT3+jBoNfxucQ5/eGMn9Z29xIWYsJr0GPrmobNjbVw2K4PdzQ4Wj4rnvuVqNK3X4+edzfWMSlFjWlHBRh5auYvJWUdZZc0WjTjhBuSqh5XxxZRLBrPn0pVQ9AbSaIXQJER0tppb798g+1xq1PEnGqARSgrjWMKPOkDL4reVBZujGVoqEOPPU0pgUVmQebyatc2ajiz/GBGZiexth+1vQd58KPlABWGDTfkUb39TnbRw6ZAyj+ztc+vxe5UmcZ9K2aFgb7NjgLTl9gZoc3oItxp4cGUFoWY9fz9nFBv2tHPm5GSC9FoCUmLQaRifEc763e202l28ur5ugMRyyrgEcuKCeXldDTPzopgzIoZZedH0egNsr1FkmRa7m8YuF+cdl8rOum6u/c9WZuRFU97kYHxGOEa9lvMeXU9GjJVr52dz//JyrCYdzd1u8r7xf3JoEJHpcPJfwedBenqQJSuUTWVcvrLzBKTXpaQmDWakPkiZ1UekKq11R/MgKVAGlONOdyNi+IIDv2FY0iDRTG/+eRTrMCE766C9EmmJQjhbQILsu1mLnjZkIKCU5v5HeHtT/UCFfWe9nTaHB51Wg06rsiKTXsOZk1O4660SXN4AAnjuyyqautz8/uRcnlxVOXCuvS093Pxq8cDPJ49Ro1U767qpbe+lu1eVrT3+AO0OD0adht/MzeL6l4qoaHLyp2UjWFAYR017D6+sr+GmxbnUd/TS0DmYUYdbDTR3uzHqNXQ6PSwaHTdAMDtaEEKDTBqLWPoA0uOEzlqk2wnRmWp9gVp/TSVqzYUm78Pz0fRZ7qKkWztr+o5JRBiOHXb6oeNnP+gji/BURSYacyZy4wvKSen4KxHeXmR0rirfNO5ExBcM9sacrUqEYdRpSm/YGg0JIxAp45SDT3jKQNlUBnzKlKHfESu+AGZdd8A50e+CxAgzWo3AH5BoBMSHmvhoRzNSQofTSyAg+bC4iZJ6O4tHxxNlNbByexNj08M4Z2oKEVbjQHAG2FzZic8vqWhyUNHkIDbURFxoEC19ov79kFJS2erkgRXlVLYq7WGA44dF8tf31Y6+1dFOTryNmXlRLB2bSGN3L3uaHdR3uIgPNWExadnV5CQ4SE9uvA2d9tC2msISgeyohvduBq8LCYphn3k8sqcDufm/iheQNBryFyp/2a465XSVO1c9V7VeZcNGK9RtQ+bPP7CHcGQGYvGfFdEsOOZ/Li95LEPKgGrzeJyqlbBPNUM2lap2kMmmfL13r1Y9SYCkMZA6USlK+dxqfVgPXfnucDAxM5x3tyqrwzCLni1VnTywooLMGCuPXTiGTXs6uOXVYmbnR3PWlGTKGuzkxNo4d0oKw+JtPHB2IQ+uqGB4Ygij00KZmRfFpyUtTM2OJDvOypKxCZw1OZmUSPMQtvbI5BBeuWoSJXXdZMbYKK13cMNLRWTHWjHpNFwyI529zU5eWlvD7xbl8PbmemJDTCwZm0BTl4srwzJ5Z3M92XE2Qs16qlqdpByiONH+kM3lyLptiOhsZGQ6GqMNIYQaR131cN8kBTD5EkT+AmTtVvUdyDgOaY1Q3s8L70J21iPCEiEyQxHNdq9GrnpIvXb8uZC/8IBkMRnwq/vt/7D18V3xk3GzOlYgcuYgNXpkVyMsuBPR045c82/Vg47MgIRCJX6RNFqJ+tcPV4o3Wp0aDek/z2kPK5el/eFRPrgDqC9Su8tDDNAjkkJ48fIJlDbYSQwPIibYyM2vDO7Su3u9lNSrADwszsa97yn/5OXbGrnjlHziQ03MGxHDij6W99KxCaREmkmLsvDGplrCLUaq23p4b2sD1y8YxpqKNkanhpIVa2Xr3g4MWkVM6ejxcMXsDNKjLBh0Gjw+ldXrNBpGJIXw4MoKbl+Sxxn/WEthSijDE4OpaHRQkBzKe1vruf7EHKYOO4wRp94upRbWB9lcjsg8XrUXSlaoJ/d8iUgaq3pgrm7EhPMVS7i3HTH2LKQ5Aul2qPZF7VZkbN4Q3oAM+JS6lduhjFJ+Hsk6OBp3IpffoSoUiaNg2pUIc7hi3i+/ffDvlT1L8QP6Ub8dItLU6M36Z5XJyQ8coKtanWyt6iQlwszD542iqdtNUngQ1zyvPMZ3NTkoq+/mL++VgoD3tjWyraaLu5cNp7nLzb3vl6PTCB48ZyQv/XoiOo1gc2Uni0bFc9H0dNrsLm56uZiRKaEkhAdhNmh56YqJFNd0kRZtITrExGVPbWZvi5PJWRHcf1Yhe1ucNHW5ueiJTei0gj+fXkCL3c1975czKjWUy2dn4HT7+NuKGsoa7Jw9JRmzQcuZ/1xHRrSFpy8ZR0L44ZGwZHuV4mCMWIws/wQ2v4IcfZpKNHq7hpqaVHyKzLxDsfA9TqQ5HE1EmvpdbB4iNk+Rbmu3IK2RsPE/g6/d8B9l47tfdVG2VanxSb8HJpz/g0goHy6Osfj8Iw/Q1ijE6GUDPwd2Lh/UbG7djUgZr3aKoYloYnKQJ94BUipSWD8skd/cbzYEqS9efwadUDDE+/j7Qq/VMDY9nHCrgbW72mnqcvGvC8bwwIpyLCYdQUalAGZ3+fAHhpa6HC4fZ/xzHbcszuX4nChCLQbe3lzHfcvLiQ42cvey4VzxzBZOHpOAUa/l8U/3MCzORkJYEE98tpdzp6YyvzCOunYXaZFmwixG1uxq5/YleSzf1kCb00tmjIWHP9qNPyDZtLeDNqeH8enh/Okd5ff7/rZGblyUw/KihsML0LZoZazQVad6yf3OOfszgDUaxNTLkG4Hcu8aaN+rDvviUcTsG5CfP6haGoA48Q61IetHXRHyg7tUaS46B2Zff8y4KB2LkKUfDrYPareo/r05/GubKbobIWGUmoEFSBoFrbsgJk+VQI1HWCb2W9DS7eLKZ7ZQ3Df/fPmsdDJjrDhdPhxuVYa2mZQZzaJR8YSY9WojXGenpdvNI58o/3JfQPLQyl1cOiMdvU7w62eVUpZJr+HBs0cyJTuS4touXllfS6TNwJMXj+Oc41IBeOGrKva2KALkVxVtjM8I528rKlhQGMc9pw+nscuNXiu4fkE2m/Z2sHBkPEatllV7W9nRd91Pr67ijqUqSdjd7KS+03XYAZreLrXWnG2qKgXID8oQS+5X1ZDQJFWmBkgZj8ZoVkp+fF3ZULbuRr5zs+pDZ05X67dfqjc49mviTtLtUOuzTX2+8sN74OR7/+c8hYNCHH4GLYR4AsgD3pNS3nWQ4/4JLJdSvnOw8/2oA/T+EIgh3rSYQpRLS7Sa4Rtg/I45ExmapDKzYbO/8cYtNDpVUo0epnaBUVmHVN6ubnXySYkqZc/IjWZbdScPrCinzeEh3GLglpNzeXtzPde9UMR9ZxWytaqTEYnBLBgZy/JtjYxND8PpUg5Xd75Vwh9Oyae61cmKIrUZae52oxECtzfAf9fWcMbEJOaOiMFi0PHgBxXUd7oYlRpGmMXAWVOSCbXoufzpLfgDkqTwIP542giklNjdXiZnRWDUaclLCMag09DVZ8HXj16vn1Eph7fIhC0G5t4K3XWqGtEvdBCVqdyPdn0OSWOQwXGIms2KPBbY5zqkVGNz+4z4yO5GxD4BWpZ/Ovj75lJV5v45QH8zItIHbuLojIoDYG9B7vocMo6H3atAq0fkzlMCQLOuB3sL0t4Ijhak0YaYe/NBnZCOBjp7vAPBGeCz0hY0GqUIde8ZBXxZ0cqCkXFc85+t9Hr8XL9gGG0OD9Nyowgz6wk16wdsJhPCTFhMOsoa7IzPCO/jc/gx6DUkR5p5enUlAK12D6vLWhneR6IM3k9pzNhHEFu3u41wq4EPtjdy25I8nl5VxXULsnnuiyp2tzg4d+rQlotOI1g2IZEPi5uOjIZ3cIxqA/Z0Dj7n9yp55LAkOOFGZHMpwmAZMud8QLRXq+AMsOtzxII/ICtTlOhT/gKl0b0vAj41ldEPV/cxr5cvODySmBBiKaCVUk4SQjwphMiSUlYc4LjjgNhvC87wEwrQMuBXhK7jf43w9IAlAhmWgiYs8WvHiuBY1YP+DhDmUEgZ972vp9fj65tLljz4wS4+L20B4MPiJhaPjqfN4SHUrOf2pXn0ePycNj6RYbEWtMCikbH8+pktXDAtjem5UbTaPfz5XVXuTo+2UN5gJy16sEclBNh7vdxyUi5/fLuE97Y28MfThvPxjuYBYQaTXmXnpfV2kiPN+AOSCKuB845L5cJ/b8Drl1w6I42yBjvbqruobe/hyYvG4nD5CbcYaHd6yIyxMCY1jLyEw8+SREgs7CcjKMxhMOECGHkaUgjY/DKy9AM1wjPzOmR3E/R2IApPQbrsEBSisgRrNKJvXGsAMcNgz2r12GD5wTO7HxtExlSkRgsdVYismYiwZOW1XbICUicgxvxCranyTxDpkyF7BvR2q7VmDlXWrm4HNJYgAxIZEofQ6b9+4z7CCLcamJQZTmasjUirgbFpYTz6yR5cXj9Xzw2n0+mhpN5OUriZU8cncv9ytTEGJfjz4hUTeGV9LQBhZgP//mwPZ09NobTBQI/bR3FdN8u3NXLT4qEBLHIfzfr0KAsXTUtj7e425hXEsrpMuevNHh7DnmYHl85Mp7nbzWWz0mntdrOluj9wCWbmRVNU08niUfF8UNzI/IJYTp+QRFrU4PputbtYu0v5UE/JjmRY3Hf7LgtbjJI27qpHNu1UlZD8hYNKidYohLtbBVK3Q62nb8K+bQshQGtAM/mibz7eFIKYfEmfkE0AMeVXypzoGMdhZtDTgZf7Hq8EpgJDArQQQg88DrwvhDhJSvnWwU74kwnQQqNFJo+BjS8iazcDAjHjagL2JoQMQFgKIvjQGdjfB1JKVhQ18tyX1UwbFsmWqg7iQ03kxAfT3O0iOljtju88NZ+bXi7G7vKh1QieuGgMZoOGxi4PDV1ubnt9J+cfl8ro1FBuW5KH0+1Dp9Vw73tljE4J5e7ThrO72cGM3Cicbj/tDje/mZOFxx/g96/t4KbFuVQ0OZgzPIaYECPPf1lNSqSZYXFW4kJNjE4N4+V1NQNkl399uper52axrbqLsgY7O+q6cXn93HlKHi5fgJw4G3UdvWyr7qIgKfSoGGsIvUm1HJrLVXAGcHUrxvewWRCbj9z2OnTWKHKZRoesL0LWbAK9CdHH1BbpU8BoVZl18lhl0AHI7gaVUVgiDouR/1ODsEQghi8c+qQpWG1sKtcphakpv0JMvACCYxEaHdJoVkz64rchoRDp6YGvHkNM/CWsfRzp6YXjLofEUUdsvtTh8rGryY4QgqwYKxFWIzctzuXq57eyu9nJ5MxwsuOCeXp1JVc9t5VHzx9NY7eL8vAgXF7/QHAG2FzZwYLCWGpaexmVGoKUgln5Mfzmua0D3ZYbF+XgcDVjNmj4yxkjeH1DHcPibZj7dAX2NDs4918biLQZSI4wk5+oKmynjEvk4x1NTM6O5P7l5TjdyozjntNHDLz/Pz7cxTOXjuXD7Sa+qmijtMHOxIyIr5E8X9tQN7BBj7QZeO2qySRFfLfytwiOVSXoJfcrEp81anAssaFYGdIgwRIFC/6gJHkB2bYXWbtVcTfiRqjq4fw7kG171PjVt4xaCSGQKeMQpz6oKl5935ljHd/yNY0UQmzc5+fH+qyV+2EB+iUd24HRBzjHucBO4C/AlUKIZCnlQ9/0hsf+J3YQyN4uJUii0SEtkQi/ry84A0gl82mOgLh88LkVK/EHUJLqcLjp6vESatbjC0juPCWfiiYnq0pbmJgRQYhJxx9OyafH7R9QGfIHJEU1XeTFB/PS2mp+tyiHFdsaiQkx0u70EB1soNejpaatl+sXDMPrC5AWZSYl0swH25sIM+vJirVxzX8UMUYjIMig4foTs/mirIU73qgkNEjPr0/I5IPtDVw+O4Ok8CCeWlVJeaNSIAs163H7AuQnBHPpzHTW7mrjhTU13HlKPh9sb2TZhCSue7EIjy/AlXMy+fUJmQNqTEccOqNi1fcbZhitivDnbIfQBLBFI7VGWP+0mn8HZP12mH0DwmhR2XjW9CG9NNlejXz/NmV9GRynCDGhCV9765+hIEITkAvuBEer8lkP+BRvwGQFXTi07EJ++CcAJQQ06WJk0hhFSOoX/vnwHqXdfQT07d1ePy98VcU9fcHq9iV5/GJyMkU1Xexu7usB72pnfKZqZXT2eNle20Vjl4t3tzQggONzIllV2ooQcPaUFH77wjbOmZrK6rJWYkNMjEoJHUKF6HH7GJkSymkPrSM10swtJ+fSanfT2K2CaFOXi3anh3anh/JGB5E2I2t2tREdbGThyDiC9NqB4AyqjH3ZzHQ+LWlh6bgE4kKCGBZvIzXKgtvrZ2t1J2PTBzNNKSVflg/O77faPXT0eL5zgO6HOMCIoazZBP1NQWeLmnAJiUN2Nah14upWv514IZoRiyCxEJFYiGyuUPa9wfEQl6dK5Ad6T40WQr9ewTxWIb69B90qpRx7kN87gP55MytwoJvjKFRgbxRCPA/8EfjpBWjp6UXuXK4k57y9yjPY2aZ2/f0s0+hs6KxDbnsVJl2E8PuUW9VRRmVbL3e+VYKU8FlJCw+dO5J/fLgLUD7QqVFmwi16THrdEEOLtCgLj366hzMmJqGRML8wlltfU+pFsSFG/nJGAQ2dbu7pI23duHAY//68cmDHffqERH49O4PPSltYNCqerh4vTref/KRQJMpC7/9eKiItysLJoxNwun1cNScLi1FHV4+Xc6emEBykR6uBW1/bwbA4G1fPy6Kh08X6PR3Udbg4eUw8L6+r5a1N9Zx/XCphlqOkwxuaiDjhRuSWl5VqmClYeUNnHI/c/pbSAbZFQ+uewde07VVZgvHANwzZumvQl7q7QWkO/xygvxHSbVeucMXvQEQ6Ir4AufklGL5IWXz2WbQOIKAEZIavOZ1PAAAgAElEQVT0GgN+cNuBww/QbQ4PD3wwWDF8cGUFcwtisZp06LUCX0AipeoBCwGXz86gpN5OoI9w+c6WBpZNSOTeXxTg8QZIizQzZ0Qs9y0vH+BaFCQHkxVjpaLJQZhFz6jUMM5/bAMAla09PPtFFSePSWDucLUJiA0NItJmYGxaOPGhJqYNi2JqdgRevyQnzoZWqyHcYiA21MT8gliiQ9QxM/Oj8foDPPrJHl7fqJKu3y/J4+zJyQO9bVCZ6OkTk/iiXJXNx6WFEh96ZESURGwusl+kyWBR5hig1pB3cF6bhu0wYhHQzwy/RSU8oPTyj6J96A+Lw56D3oQqa68FCoGyAxyzC+gvP4wFqg52wh9tgMbVpfpea54ApPKpnXoZTLtKZVLhadBdDzoDYuRpSHM4Qv/DWBLae71DduE+v+T/FiiJydQoC+1ON812D1urmnjonFHsbnaQGBbE9ppu8uODMeo0PPLxHhLDB4f/G7vcaDWCT3Y2Y9BqSAgPwhuQQ8phO+vs3HJyAqUNdqpae9jd7GDdbsW0fPi8UVzxzBZAkcre2FTPgpGxffrEEluQjma7mzaHh398qKRH1+9upzA5hOxYGx5fgDaHm/gQE1fPyyI10nzEnV+k2wENO5AdNYiEAmRwnCK5xA1XGt6TL0G27h68eTjbIWfOoBJcwRKkzwWV61U/LTJ9iIOSCArdj0R4lGUVf+xoq4Qtr6jHjTuR0dnqRl61DkaeCmEpagrC2ao+79g8ZZ6QaVXyn95exOgzkL0d31k//WAI0mvJjLYOMJ+zYmwEGbTEh5i4dn42Oo2GqGADOXE20qMsPPrJbs6bmoItyMBnpS20OTy4fQE+2dHMzPxo4sPMJEeYhxAhX1xTw7lTU4gJMZIRbSUg5ZCZ55AgPR6vn65eH4moTfUTF43lz++W8VVFK2ajdoA0JpEUJofy0DkjqWpTwidSwg0Lh/HWpnrmFcYOBGeAl9fV8MqVkzDptextdvDWFmWbuXBkHK9eOYkejw+zUcfTq6tIjjAzPSeK6O/pGT8EiSMR825DOlsRkZlgCkaWf4xsKlPVkO1vQlcDInvW4Gt6OlQA74Ns3X1U/b1/SKg56MM6xZvAaiFEPDAfOEMIcZeU8pZ9jnkCeFIIcQagB0492Al/vAFab0bamxko0fR2KtejD++BxNGqJNc3HiVrNiFOuvcHu7Qom5GCpBCKaroIs+iJCTFy0yvFXDYrg5tf2U6H04tGqB3ztS9s5cSCWLQCCpJCqGx1sqO2m5q2HpaOTWBl38xzfJgJk17LjLwoFo2OZ1tVJ3GhJhaPjuftzfUIodx7unt9fLSjmavnZfHCmuqBa2rodA25xl6Pn0irkXCrG61Gw7jUMAxazYBEYT+MOi2BQACNgDtPHY5WwLX/KcLjD3DT4hzOmpw84Mh12KjbpkglgCyNgpm/VSXV8o9VFp0wUrGI3Q4wBCGMFmRLBWLC+RCVrZjaDTtUv7RmE2L+bZA4cvD80cMQ036DrNmsbiqRx/5c5rGFvrtXxvFKJjIoBBbcqcZtzGGIkHgliNFcDhnHgVaPLPkAMfPaQ35Hrz9Am92DSa9BAlfPy2Ll9iaCDFoWjYqjrKGbG17aPuDDfN7UFEalhDIs3sbo1DC8fslVz23hnCkpWE06xqaFIYHhiSFYjDrGpoVy5uRkXviqGp1GML8gjvuWlxOQkvvOLGRlURMPnDWSf368m7hQEzPyotm4p4OoYBP9yglfVbTxVYUqQ//jw91cd2I2f32/nCcvHsvpD61lXkEsK4oaBzbtD35QwS+PT8Pe6yMu1DSwNkclh2LSa+nq8XDDf7ezca+q9qypaOPxX46l3elhyYNfDWwoblg4jEtnZhzyZysMFkgaNbB5knu+RH6uqq1SfISYeysYzRC+T785OAas0Up1TGgRCSO/fuIfMQ7HJEhK2S2EmA6cAPxFStkIbNvvGDvw3RjK/IgDtAgKhuiswYxIHwQIRTDy2FW5sx9eZb4gA/6j3oNu7Ozl189sZmpfGWtYrI3i2m56PX4CAUmHUy2ugIQ9zU4iLAamDIuisdPFc19WMikzkkmZEfgDknanh5sW5yAljEwJYXtNl+oPP7kZX0Dy1uZ6/n7OSLJirAxPCkYD1He6+NXMdFweP1mxVir6+stSSi6flcFjn6rMfMnYBHY1ObjuhSJAlf/uWTaCxi4XF01L4/mvqhgWZ8Oo0+CXsPz/jsPj8XP9S9vx+FVJ/u63S5mZF0169KHPhu8L2f83C0lQIjSrH1HawaOWIbe9jghLVGIHs6+Hqg3Ij/4CQiDzF8JnfxuQKhRTfoU0WZE1GxH7BGhhtED2DET2jCNyvT95RKTBqNNViTsqU82rx+UrwlBfZaLf53v/14mAF9lRi5hxtRINOgS4vH7e3lzPn94pJTnczE0n5XDJk5tIjbRww4JsXllfy4jEkIHgDEpd7+wpkowYK2dNSub5r6pxuv082jfv/K8LRjM5O5LNlR1UtfaQEBZEZrSFxy8cQ1VrD89/WUVnj5eIPq2CVzbU8tHOJp66eCyf7Wzhyc/30mJ3c+G01IH33H98v//n6rYeWh0eOnq8xIcFkR5jZe6IGJxuH2lRFu55t5Q/LRvOF+VtRFgNzM6PRqsR9Hj8lNYPKgaW1Nlxenx09XqHZPsb9nRw6cxD+mgPCNlZv88PARAgooeay4jgODjxduiqV1WTvhFJ2dUALeXKUCNm2FFn7x8ViMN3s5JSdjDI5D5s/CgCtAz4lUJRwA8hcQPi7tIaq5xXPA6EwapKLz4PtFcjxp+LrNumiC2Jo5F7vlRCF9mzBsXhjwK6erxUtvVS+ZXKXguTQrhkpvoSG3QazAYtPR5FGhmVEsq8gljufHMn5x6XzEXT01m/u52r/7OVW07K5bd9wRPgyjmZPPrxbq6dn41vHxGTDXs6WF7UwNlTUlhb0crFM9Jp6XaTHGGmMDmEsgYH8WFBbNzbTkmdnUtnpjMuPZyVRY1k7Teu4XD7cPsCHDcsAoNeQ01bD39fWcFD547CqNPyny+q1Xxmn9xocJAOo+7IbXhE0ihk0ZuIrBlKgUgGoKMKGZsHs65H7vkCufm/iPyFyMTRiFP+Bghw25GOQWMMWbcVkTwefqCWxk8F0m2HjjrQ6tTUg9GKTJ+s/g6dtcgvHoXJFyHaq5BRGd9MDtLqITYfEXsAdb7vgd1NDn733+0AbO/p4uW1NYxICsGo02Ax6fhgeyOBAIxPD2P9HpVtHjcskr++X8ZvT8ymqdPF8TlRrC5rpaLJQaTVQEa0lQ172vllnzd6kEHLlSdkct0LRTxwtpqjTwwP4pbFudz4inrvDqeXug4Xs0bEUJASSkqEmbR9NqVzC2L4rKSZHXXdnDYuiW3VnViM2oFe8YoiNaZl1Gm45VXFKQkO0vHI+aO57oUiJGozEmTQkhFjI8Ki585T8wcIn5fPziDCYkCnEUzJiuDLijY0As6anHxYn+/+EEkjkUWvqYQmLBlpiz1ga0KExA/RtZc9Hary1SdKwujTYfQZx5wz1LfhZzerQ0V1X7YkAzDuXBh+IkJnQkQkg7MZajYhEwohJgcx41qksxkZlYk46S/QUYOsL4Kd76tzRWYecChfOlqUH7FGB1HZav75EBCQcPvSPGraenl6dSWXzkzHYtJxz+kjqGlz8uA5I6lp6yEq2IjHF8AfkFw0PRWPD658dgsWo45r52XT0j101MKk13LZrAziQkxkx1opb3RgNmjJjLGSFB5EepSF3DibytCF8ohud3p44vM93LYkn9c21LFsQiJ6rYbmbhfzC2MJMmiJtBlotXuIDjYSHKTjrrdKSI8yc/vSfGJCVAldKwTFNZ0891UVNyzMwaTXYHf5uHpuFgnhR3CzE52jtLNdnfuIkAiEJRxZt1VlcoCs3YI4+a+IiFRkZ53awJnDVH8MZcohPQ5E2oQjd20/cUhPD3LzK1D8Nv0jimROg8YdsLWvD50wEnrakeufg4KTvz6WdZSh12m4eHoaL6+r5cU1NdxyUh4fFTdx6cx05ozowReQrKloZWZeDOc+uoEWu5tfzUznzElJWE2q1ZQeY+X9bQ0D5+z1+PH4A3T1etFrNbx21WQCSNodHrR96VROvI1dTQ5yE4LJz/36rHBalJW/nFHAlqpOunu9zC2I4fLZGaRGKunRL8tbyYq18emOpoHXdPf6sLt8NHS5CDJouXBaGjqNYNPeDh75aBcRNiOvXjkRhHLEMui1ROm13PuLAvY0O7EF6cg5gtaUUkpkeCpi9o3QXKaMNOq3I62RQ3gcB4TXNWjvC1C5DkacrJQYf2T4WYv7e0K6HeqGoNEhCpcqpmhbJTJ6GEJnhPQpkDZZzd0525Hb30ZkTEFufwvp9yGGzYbdqwdPGPAf+D2+elyZMACMOAnGno3QfcsXcz/sqOvizIfXYXf5yI6x8uqVk9hc2cGdb5Vw4fGpjE4No8ftY0xaGO9va+TtzfU0drl4+pJxXPj4RnwBicvr4YU11Zw2PpFLZqTz+oZaxqWHMy4tjBa7G6fLxx9OyWd3s5NwiwEpJXNGxKIRgtqOXu58U+nr6rWCe39RwJKxCeg0gjtPyeepVZVUNDlYMiaeqGATNW09PHj2SDqcHoRG8Nv+ES2Nhtr2Xt7dXE9atIUgg5axqWFICX9+t5RRKaH8dn42E/rGWRo6e9le04VOq6EwKYSIQ1RBEhotRGWoedpRpymCkjUSGQgoIlI/Aj5wNBNwtMCXjynC4IxrVNlNq0PW70CMOu0bM7yfcQD0dPQFZ9RnXr8DkschzBGKrTv2TCVcsvm/igfQsAOZPesbXYxkX1sJnVH1qg8BGdEW7jw1n3veKSUx3Mz5x6Vy/mMbaO7bvLY53JwxMZmbXilmyZgEHv1kDycWxtLY1Ys/IPEHJA9/tJvfzs8iIdxMpM1Ir8fH5KwIPP4AOq2GrVVqU5efoGRxO3o8mI06smJt3LQol+r2HtocHh78oIJx6eGkHsDEQkrJS2trBsroaVEWThuXSIfDS0qkGW8gHKfLy4TMCJ7+ogoplSd7UngQ+Qk2ThqTwGOf7hnwel82IYn7l5fT6/Vz8+IcrKbB+1C3y4fT7cMWpDtiwUR2NyC3vgpdDcoko2SF4hVodIrD8Q16AdLRqvgeOgPMuxW+fFwRczOnHRW73h8Ch1viPtI45gM0Wj2kTkKYQ5FFb6ob9dZXEQvuUmpR7FOW6OmAoGD1pWndpUYBWirUzb74XcTki1TPsqdjqCas2wlVGwZ/3vOF8o3Wfb8sek1F28Bcc3mTg9r2Ht7aVM+JhTHkJYbw7tYG8hKDKa7t5vWNdVw6M53nv6xGg0DXNyYCqhSeGx+Mz9/J/JFxZERZWFXWwuqyVrZVq9GWW07K5ZblxbQ5PFw7P5tWh3tI1u31SwJSzU3+4c0SLpqeRkWT6ke/samea+ZlsbyokWFxNixGLV6/HGCqLh2bwC2vFhOQsGFvBxdNT2NbdSe/WziMd7c2MC0niuy+8nhXj5ffv1rMxzuVUtrls9K5am4WhsMofQuDGQqWKs1fnUHd6H1uZM0WJTeYOApZvRGROArpVO8rP75XCWmYbJAZDs3lBIxWNPv0R6XfqzZ6x9gu+dvwXfV9Dwt6k2JkhyUrEYr6IuTOFZAxFWZcg2zYqTS6AbnxP4r49Q0tBOm2K/erojfVNMXMaw9p3txk0LFsfBIz86Ix6bTY3d4hQiOt3R66erw0dbmpbO3h7+eMpLzRwdpdbZw9JZnVZa1sqepkTFoYNW29ePx+9rY6SQg18czqKuwuH9fMy2JKViQnjY7n6dWVPLO6irhQE09ePA6TQcPfVqixrgirgZjgA/9/ezz+AaVAgL0tTuLDTVz4xEbCLHqumZfNXW+VcPPiHP594Rh63H7iwoKwmfQ8fN4YVpW10GpX/6/a9l4CfU3shg4X3T0+Yvr2NxWNds74x1o6e7zotYIXr5jI6NTDV+eSRW9C2cfqccsuxMhTkJteVNK4B8meZemHiKAQJVTjdqh2Y1AoIiLlR7fGoG8O+hiL0Md0gJaeHuTuL6Bhuyphx+aqbNjvRTbuRMQMJTAQFALxIxE6HTImG2GJVPaF1mhluvD5g2pEJ3G0kgTtt9QzmpVtXk2fSEzqJOUf/B3h8fqp73QNmU/UCAgx61k2MRGPL0CL3c2HxU0sL2rkslmKNHPve2X8adlw7C4P95w+gnvfK8dm0nHt/GzqO3p59stqatt7uXpeFjqtZiA4g5IMzY61sXZ3G0nhQWp+WQgMWg0ef4BwiwGzXktyhJnuXi9m49CA2S8wYnd7SQg38chHe7hxUQ6flbQQaTMSkDA7P5qUSAvBJh0hQXrMRg0vXj4Byz47+tr2noHgDPDW5gYumJZGhPXwetPCEASGvpu6NQqpMyJm/RZa9yC76pW5fES6Urpy25WcICA3vgCdNYo86FwCE85T3rVV69X8dEwOjFj8P7NE/L74rvq+h/0+lgiYdwu0VSE/e0A92VyOsEUhW6uVsEvWDKjeqD5vc/iBLT4B2qtg2+vqcdtu5J4vh5jafB/odRriQlWWbjZqufWkXG5/YydajeC6BcNIjTITaTPwYXETY1JDB/QGNu7t4Pcn53HVnEz+8eFuvqpQ6+TCaWkE6Qd5IA+sqEAjBGPSwnhmtRpJbeh08er6Gq6Zl81zl42ntdtNTrxtSN95X1iMOk6fmMTtrysDkSlZEXxaotZEh9PLh8VNFCSFsKqslYKkEFKjLGyp7MDnl8SGmojaL/BbDDoMOg0LR8Xx2sZafrdIGVhUt/UM6IZ7/ZLtNV2HHaBlwA/dg6V3/B5lkpIyHjHmF18zt5AyoLQHnK0Qlaky735Rms/+hjj1oQFv9x8jjrH4fGwHaFp3wRf/VI+byxDjz1e+s6DE3vsgHS3I6o2gNSJMFjWbFxyH3PEe4rgrkOWfIA1Bg/OztZtVObQvQAujDaZeCs0zlJBJ9LADepseCG6vn9c21HHra8UsHBnHnafms72mi6VjE1hd1srDH6mZ4pRIM2dPSeHp1ZXUtvcQatYTG2zE7vLxwpoaOpwefjM3k11NDmraenhxTQ0zcqN47stqjDoN9l4fMSFGmrpUllyYHMqGPW3ce0YBm/e28+bmBn47P5vHLhyD3eUlO9ZGbKiJOQWx+P0BVpe3Mr8wlh213ZwxMYmMGAvDE21Myojg85JmzpqSjNsX4PLZ6Zh0Wp66eCx7WpzoNIK4EBPLixrJirVR3dZDZowNfd84VofTw5jUsL55apieE4XNdOS/ViI0Ednbhdz0EiD7VMa8qiri94ElHOn3DbrzgJIy9HmgvRL5yX3qdS0VyoQj/8Qjfo1HCdM5iL6vEOIS4BKA5OTDJA0ZbeBxDH2uqw4Rn4vc8Dz4XIgxZ6jydb8V4YEg9tucfVsP87tenl7LsgmJjM8IR0qobHVSVN3FkxeNxSclm/qIYv0IMmgoa7APjEDVtPfS2OViZ103WTFWShvsGPUa/AFJ435jiKFmA2ajjilZkVS2Ommze6jr6CUh7MAl/SVjE8iKtdHh9GDSafjVU5sHfmc16eh0eilICiHYpOOdzXUYdVre29YIwNVzM7lxUQ5bqjqZlR+NzaTjT8uG0+H00tXrxddXjo8NMQ2xh82KPfzpCaHRwuhlyKZSVZ0qWIpMm6xMhA6UBbdUKFergE85/e1jWKMey6+/5kcCcfhCJUccx3aA9vQO+VHqTTDmbEREyoAtmgz4lTZz2ceIcWcj1z6pntcaEKNPV1+6wlOhpRQqPoP+5x0tyIZiNT6iM6mM6hCyqtr2Xm59TQkQvLOlAaNew1mTknG6fawuH+ybVrWqoGzSa5iYGcEX5a08fN4oVpe1YjXpmJ0fw2vr6zhlfAJhFgO/mZuJxahjWk4UHn8Aq1FLfmIwe1ucJIabGZ0aykXT06hscXDdi4rtffsbO/nl8amMSw/HqNNQ3uAYCNatdg/RNiO/OC2fh1fu4pX1Hm5fmsf1LxZx56n5FFV3EWE10OvxY9BqueONnVS29qDXCm4+KZd3tjTgC9TT3eslP8HJnBGx6HUaNBrB+Ixwjs+JRK/VMCY19LDK2wdFVDZi4V3K8tAahRRCGcr37fJlV70iMtUpq0CROw+hMyC9bobcOHo6DnDyYxYH1fft0wJ+DGDs2LGHd3dsLEX2dKjg27ZXqaxZo1W5s48EJNc/B0sfUG2Ib0J4Kkz8JRS9AZGZR1TIwmRQ5KgHV5Tz4EqVLZ8yNoGLpqcxLj2M+FAT9Z0uzpyUhISvzfVbTTo8vgAnFsawbEISyZFB/OmtUv56ZiH3nVnAIx/vISfexvE5kbR0u2npdnHra8VsqeoiO8bKvy4cQ8oB+tA2k55JfZwMh8vLw+eP5q/vlZHQ11Pu6vFi0An+/dlepmZH8uTnlQOvfezTvTz7q3HsrO/GoBV8VNzMqxuUgcddp+bj8vowoSMvIZiXrpjAzjo7qVFmRqccmVEmEZsHS+9XEzC2qINyN2Rb1aD8btV6xAm/Q65+GNxOxPG/VnoFP2L8HKC/DyLSlNVjcxkExyHiR3y9l+X3QGOpUsHpqBn6vBDI9kqEOQLSpiB9XjDakFtfVqIWgDjhJkgdf8iXqNMKjDoNLm8Aq1HHqJQwTvn7GmJDTJw+MYmivrL0mNQwRqaE8Oyl46hu6+XMScnsae7hkY8VsWRVaSt3nZpPV4+X/3tpO1E2I4/9cgyTsg7uu1zf0YsQg7OXJoOWP71TwvnHpfKHN0vQCDXO9cdlI4gJNnDF01sG+uR3vVnCOVOSkRL+u64Gjy/ADQtz2N3sHJgt9folO+u6iQ4xUt/hoqa9l09LWhieFEJKpIXC5FBa7R4+2N7IrLxohh1BZun+EDq9msONU+M7+y8lTUg8ctqVqsSqNw3aWIYlqd3+ni8gKAyRMeWoXeNRwHfR9z0yCHhh62uQcwIidSIyNBFZu3XQJ9poRYw8DVrKka5uiMo4oAGCMARB/olKrERvOuJjjS6vf6CEPC0nkhn50dz7fjlRNgP3nVlIV6+X97c28OwXVZw7JYUHzyrg359XUZAcgkYICpJCqG7v5a3NdUzLieK+swoH5DVz42y0Odxsr+nmsqc30+H0cvmsDHo8Acoa7FQ0Og4YoPeF1aTnhOExDIuzcfvrO/jl4xvIjrWRnxCs5rQnJ3P1vEw27e1kZXET03OjqGiwc+6UFGwmHb95flDb4unVVYQE6flqVxuXzcxgZEoYIw/T7vVAOJBW9/6QPg8iIm1wqysDSsHx5L+qoG0O/0G8Do4axLeaZfzgOOQA/UMQV4QtGk74nVIJM9qUs8r+x+iDYMQi5Kp/qLEboQXpV2YKthjY+AIkjFL95oypULMFmT1TRbQtLyNrNyEOI0AnR5h5/MKx3PVWCePTw/ispJmAVIIh63e3c/9ZhVS39eB0+3h9Qz2XzEjD6faxoqiR+YVD7RbNBh33vFPK1XOzCLfqCQQkjZ29hJgNBBkO/MXPjQ/mkfNH88zqSgqTQsiOtXLWlBSsJj2/PzmXzh4vVpMOl8dHhM1IqEU/EKDToi1MyIigq9dLd4+PWfnRvLimmhML4zDp1aYD1JhHf3VgXHoYaypaB3rYFqOOxaPjWTz62xf4DwFhifia77Mwh8LkS2DUqaC3IGw/jv5zH76Lvu+RQUyukussXYlMm6wkVnPnIYbNQn7wR0ThUqWN7nGC0KhqRmzeAU8lNDo1+nYUYNJrWTYhiaKaLs6YmMz1LxbhcKvvtC1Ih16r4e0tapTq5leLue/MQm45OYdWu4fmbhcur79P9CeEp1ZVsmFPB3cvG862mk7e2drA1OxI3tlST32HKns/sKKcq+ZmUdZgJ8Ssp9XuxmrUYfqGNdmPULMerUYgJZQ12DlnSgp5CTYk8NSqKmJDTDx6wWjK6u2YjTo+2tHMuVNTBqoAoJjsH2xvJC3aygfbG7lw+sFdpL4LpJTqnqrVDzpbHex4Tw9y9yoo/UhxdRb9CTpqEOEpEJH6zVyEHxmU1OexFaEPKUD/UMQV6PMI/raFnj4FEZKglMIW/RGc7Uh7E3z6AGTPhIhUpNeFXPeMEv8HdWNJn4KILzy86xOCKdmRvHLlJHRawXNfVPFhsRLN2F7bxcSsiAEm6O+X5PHqhloibUZ+MzcTq1E/MIecnxBMZLCRK07IpKSum+5eI/cvryA33sbiMfFMzIg44M5dr9MwZ0Qs03KiWFXawlXPb8XtDXDVnEz+u65moGd93YnZfLKjmWvmZfPvT/cwLj2MMIuRX/xzHYnhQdy6JJeNeztweQM8taqSGxflsrvZwZjUMBLDTfz9nJG0Ozy8s6Wev509kvhv6MUdSQQ66xDtlaAzKi/ozlpE5nGKdaozIYYvVNZ3+0A6WsDepDykwwZ7siIoGIJ+lNrb++v7TjxabySCY+CEG6CnE1m5Bt69WfWlT7xdicI0l6vgDCADyNa9qjxK/1OKePVDZFGz8qLIuWoSMiAHgjNAm8OLfh+mj5SKXAWStbvaeXldLb+dn01hcgh/fb8cgDW72vispIX8hGCEgICUAzPQoG7a8SFBPHzeKEoburnquS1MzY7kmnnZQ9ZBq93F+9sa2VLZydJxCUzKjOC2JXlMz42i0+mls8dDWpSFq57bij8gqevo5aW1NSwdm0Bli5OUSDMxISbuOCWf1aWt6HVKeveRj3dz9dws2p2DKmKHChnwQ/Um5JePKlLttN8gIlIP/qLW3fDFo32PdymWdu6cw76WYxGaY2yvcagZ9HR+KOLKd4DQGZW83L5POtshZbwykzdYkM52qB9U5qK5HBbepcZKjgCsfcSok8bEE241UN3aw+zhMei1EGbWkxJhZmVxE8u3NdLZ4+XGxTn4/JJlE5Iw6DS0Ozw4XV7CzAay42z73DzaGZ4UQqfDy6Wzvm6JKTkAACAASURBVFky0ajX0tnjHXDG0ggxEJwBNu3twC8l//diEc9fNh67y8fFT2wCVH98S1UnkzIjmDM8ht/9dzt/fKuE+84q4B8rd1HW6ECvFdy9bAQnFsZSkHz0ZfwCrXvhs78hO/rMXkafDiHxiuzlVKQf6WxFTvuNCgh+jyrzf/IXZfKgN8G82xB9XIUfKw6g79v1LS85LAhTMLK9Gja9qJ5w25Hln6r1FfArG9A+swRhjVJ+28Gxyj94/bPKzWrcOd9+0z8M7G1xct0L29hR280Fx6dy68m53PlmCQathrnDYzAbtXxS0kx3j49rT8zC55cIBHv7LCnf3drAJTOGZqIBKSlICuGlKyZS19FLUriZDmcxrXYPd5ySz+z8aDbs6eCD7U2cf1wqHl+A3c2OIQF6dVkbdR29LB4dj5RKCU2r1ZARbeFXT23mrMnJaITgyjmZ1LX38sr6Wjy+ANurOxmTHs6IJFVm73H7mJwVzpaqLqKDjaRHWwg16wd0Bw4L9ibkx39RJemeduTaJ9Q60R4kFHj34wK5HEfE/ORYw08mg+aHJK4AAa8L0VymXI5C4pWM4LfIOApLOLKtUu0WLRHI8DTlfFS9nv/H3nmHt1ldf/xztSVLsiXvvbedPckkkEUCYY+WWWhpocyWPQuUlu4WSltaaNl77xUge+/lON57y0OWNe/vj+vINhuSQMKP7/P4eSLp1es3lt577jnne75fkTUd7IlIR9rnk12+BuLsJk4an0xFax89Hj/1HQPotRoeW1XL/NJ4pufF0NDlQacVJDvM/HNpZVgVbEFpPBajDrcvMOKcoRD0f+y5j6PZ5SEnwRouj/UNBMiKjaCyTS1K4zMd/PvDKgIhidsbpLPPN6J3bRxkh9783A4umJnBjPwYOvt8lA1qefuDSvjhuDFJYbeeQwHZ1w7tFQgph4IzQNNOGH2yInjF5asZaCHA24N86y4w2xFjTlefOYB/AFm1CuxJCMvXE8o4XHCw9X2/EAazCrT7GboWJ6z9nxpPm3wBmGzIoB+58XFAII+9Ft77nbLwBGX7uugOxCFyC3t7WzOba1wA/OuDSn53Zim3n1SE0MAdL+/irlNL+NXJRVgMOv72zj78wRBXzs/lh9PS2FTjoqypl+5+HxfNyuTJNbWMTo1ibHoUb2xrJsVp5piiWPq8Qf774wkIIYi2GpEod6qpOdHUtLvRalTAL06OxGlVEx8Oi56kKDNXPb4Fq1HHrScW4bTq6RsIctMJhWTERnDJ/zbR0edjQqaDnx2TRYrTQnZsRNjDGtRm/8L/qM2zRsB/LpxAfpItPG52QJChkczrYIAvZF47MyFplEpwIpMQiZ/e1jjSIWQAk6/9iw/8BvF1A/Q3R1wBRMse5Dt3qywJEAtuRcZkq3k8GVK2gh+f1+usRb52U7gkJxb+Cll6PMIerzSFhQYx93pI+zz/7a+HDVWdbK3txmxQ1nP3vbuP82ZkcO+7FcTaDMwrTSDaauT+9yu4+OgsEqJM9HgC+AIh9rb0EQpJLpydwWMraylMspPoMDEqJZLW7gEqWvuIMOkoSLSF2dJr9nVwyf824QuEuOeMUrzBIOkxVs6amkpZcy8GrYbHV9XQ4/Fz8ZwsLAYNvkCQK+fn8vSaOlKiLZw0IZmtNV387ZwxtPX4eG9HC3OK4jhpfBIbq100uTyEQpJ+b/CQBWg50INcfr8agytdohSMegc1tuMLoHk3zLgUOiqVL7E5ChFfiJx6IbTtC/dG9y9Awhypem1HeID+xuFMRxxzDXLn68pSMjoTihYit78aVnQTk85VmymfWwn9eFxD7+/vHOkJfZCh047Mcgb8IW5/Uc0gRxi1dPQOkOy08KsXd1M2qBt//dPbOW9GBlcvzMMfDNHa62VqTjRaraCuo581FZ0s293KmHQHPn+IXzyxldK0SG49sQiNRrC8rC2s9jcjP4Zkh4ln1taTFWdlam40PR4/Erj7ld34g5IeT4B7393HtYvz+fkjm7EadRw/NjEstLKhqouTJiTz65d3kxZt4enLpmAb1BcYXvkKSWjpGWB6/ueTRb80bPGI2Vcil90HJhti6oVfKOUpbLEw52rl/220Kp7HxyBdDUqbwhABCYWfWI+PGAzfvBwG+LoB+psjroDamQeHFISkuwsaX1JjHADjz0YWzkMzvMfobh/qlwGytQwRmagkPQd3kXLlv5CRyYiuWkXfi809oC9We4+XnQ09tHR7iLUZufqJrfzuzFHctKSQ59bVUdXmpqrNTYRRx+KxicwpiuexVbXERxr50cxMKlvdCASbqjvJibdy3aJ8oiIMbKl2kRRloqLVTWvPAHuaelkyLol5pQm09gxw4zPbwwIG1z69nXeumxme1zTqtexs6CYnwcaoNAdLd7YSCIYYlRqJI8LAdYvzibebuOnpHVwyNxsGe3b5SXaeXVdPdXs/Z09LI85m4PdvlFOYbCfhIBnGfwKebhWcAXa+jph6oUrxA15k6x6oXjsUOAA8LuSOVxHpk5A7XlHzzVMuUK5Y1lhkXzvCdHCctv4/QWh0hNwd6p5o2AK730LMvgI5TG5Vtlcq20FPp1rop12M/Ohv6v1H/UT1Nw8R5pbEs7q8g2113Vw4K5PJ2U5m5EXT6fZz05JCzHoNr29tpndgqGfb6w2AUOJAAFcvyOWW53eEyVjlLb2cPyOTu17ezfPrG7hsXg6/fXUP6yo6SXFaeGxlTVjpb3lZO1cuyGVStpPyll4sBi13v7KLi4/JRii5HECVS33+ED+fm4MGRWAL/40F9A4E6PcFMeg1I0qruQlWIoxa3N4gMTYDbm+Qbo+faOuBm78IrR6ZNU21fjS6z13vpN+rVPwMZuVO9RkOVdLdgVx2L9gTkAO90FWDGH/WAV/rNw/5SWuybxlfN0B/Y8QVQDmn7FeMElpwJMO6/6nXSpeAqxbevB05+iRIn6Jmn81RQ6M1CER8gRK3MEQM7fZNNqjdoPowAEXHweTzVE/7K8I9EOBPb+3lqTV1JEaZOH5MIneeUsy7O1r4cHcrM/JjOW9GOq9saiTRYSYzNoJz/rkOtzfIpcdmc8VjW8K+sDcvKUQjBHe8pLKCZIeZ48clcvkjmzlnegbTcqPxB0IEgiH6vIEwoxpApxF09fm457U9nDA2kbtf2cPtJxfz2MpaPIPqST8+OpNIs56aDjcDvhAIwQ+np7GlxkVlm5vlZe1cMT+X7HgrEYO99aCEmQUxmPQa/vLWXnYM9v+m5kTT5VbGAlERX07c5TNhtKqMrUvNWsqeZkTqeOQbtw4dE/SNLL/qzUrYH6CnCbnuEcQx1yJ9bkT2zE/d7X+PL4GuWmjcHn4ozVGq1N3fCYBIHo1MHoOIy1U96IhoRHSWijyRiYeUKJYeE8FfzxlDvy9IlEWPQafl3xdOIBCSWIw69rX0sr6ykwtnZXLPa2UEQ5JfLMwjzm5kfmk8ZoOW2YVxvLG1ORygTxqfwm3P7yQQknh8QZ5eU8evTy9Bg6Cm3c24DAfv7mhFI+D8GRkUJdmxm3X8+uU9mPQarl1UwM76bv55wVi21HaztaaLHxyVjs2s43/Lqul0+zhzaio/n5vDpqouTpyQxBtbmyhItHH94gL8waHMLTM2gusW5ytSmISyxl4iph68iVih0X6q5oMMBdW95/MgNTooXwp7P1DVqxmXqM+5u0mNMRqtSkNCb0L6+hHpk5F73oGIaKXfHvB+rXX028d3IIP+pokrxOYijr1OsXNt8UhHqhJxN9rUXLTJpgwvlv4JlvwO1j8CjTsg6yhYcCtCa4C4PKUONu8G5OoHlWDJpPOQr98y9HsqlsOYUxQR5ktCSsm2um76vQGeXafEBfyBEOMzHVS39/PuDiWjt3RXKzcvKeTCWZlsrelmW62S6VteptiaTcOUjPY295LmNPPvC8fT0uPFGaF20edMz2BdRSf/XVaNUa8hPspEqsPMBTMzePCjKrwBtVuvbnezvlJl4dXt/dR0uPnbOWPYUd9DXoKVpTtbeX5DA/GRRi6ek81tL+zkr2ePobvfz8MrahiXEcW+lj5e36J6imnRFm44oYAW1wDvbG/hb4MCESvK2nnoJxO49qltRBh1/PEHQ/OkXwfC4oC51yGbdqlZ2sRiZNNuGHUibHtZjc6FpPJ73v4y2BPUqIfQICNiVNUkaTTEZKH5PjB/LUj/gFLtS5+sZHb9/WqjqzUo96qgHwwRyIQiNMM0CYRWD85DTwjdD6tJP8JEwqDXsn97mBNv45YTi/jX+/u48fgCxmZEYdZrcXsDnDMtHb1OgzcY4JYTC/nz2+X4AiFKUyOVDvNglqzXCpbubOXVzU0kOUw88KPxmA1aHBYD/1xawUPLqsmOj+Du00q4/pntrNrXzikTUrjntTLqOj384rg8Is06NlZ30elW1b+nVtdx85JCJJIYq4EZ+bH4AkHWV3ZQ1drLtPxY0qIjcFqNTM6O5v0dLRgNWi4+JusLR7oOCuo3q1aiDCGO+gly99vq+cZtyLpNkD5RvT6o1ifm/BKypyMCXuT6R9WmuacJaY1FRCYhIxOPvA3ydySD/kaJK8JggaQSoEQ9BkLjf6DmmJcPSoGWLoG+NkRnFXL/zr9yJcKZrliH0ZnItnKlOpY+WblgmeyQMhaqVysFnHFnKgesr3BtZY29bKt14fYGGZMWxcbqLk6ZlMI1T237BFPUEaHnF08ot6l3d7bw13PGMCUnmqxYxdLcX6bOirNiM2pp6vLQ5w2S4jBT2dZLitPMf5f1AOD1h3hrWzMXzcok3m7kh0elsaepl9++umfQBacwzCz3BySvbW5iwah4JPD8BsXva+n2sruhB6tRx3Pr6jl+rJplTnaY2dXQE77u2o5++gYCNLoGMBuHpCB9wRCbql3hedGbnt3OEz8bqdX9VSEik8KiCdLXD5ufgqJFiHFnKL/iFfcj846BwoVgi1WbtoAPZl+JCPqUM0/1Gsg4ChHhQPa7VNZnjEAc4SpH3wiadiDfvktVrEadhEgoREYmDVYsClXJMyp5RHD+ttHZ5yUYgli7kcYuDxuqutBqBDctKSIu0kRVm5vrnt7G5OzosOPUxXMy2VzdxXnTMnh5UyO/f30Pvzm9lD+8UYbVqOPnc3NYubeDuSXxvLujhfpOD+dMS+fNrc3sblR97YoWN90ePzedUEhJso0n19SHSZV3vrSbe88di0GrZVjcJ9Zu5NiS+EHFPoHHB+9sb2VithOr2UWPJ0AwFGJrTTf//KCSQFDS2uPl53OVsuChQliRcX9lalh7EFDzR+6uEVK6smI5Inv6yIoWKOb/+kcgIlZl3sYjxFVO8t0J0N82hABZ/sHQE7XrYNJ5arEecaAWdryCzJ4B79ytvnh1G6FlNxx7HWLqhci8OQhvH3LFP0CrR867EZH45czm3b4A/1teQ1Wbm8vn5TCrMJbRqZH896NqGro8LBqTyKrydo4tjifyY+QqV7+f379exviMKH5/1ih21PdgN+mIthm486XdnDMtHYtBw4X/2UAwJPnvTyaM0OItSLRT097Pir3tlDX1sWpfR/jcsTYja8rbefxnk2jpGWBmQQyXP7qF6xaPNBixmXQM+IPER5p4cWMDd5xchNWoozQ1krtf2QPAcaMTeHNrM5Wtbn40K5MPd7fi9gY5bnQCte1DN7IvIA9ugUhnhMTSQU3tAWUHaohAZM8Agxn54i+R+xmoMdlIa5zabAFSaCBtIvKje6FxK5gdap7XmX4wr/A7B9kySCfx9sLGx5WN4O43YddbyMRixJQLRmx0ZNA/ZCv5JUQvDja21rq44tEteHxB7j1vDP94r4KP9qhe+Q+PSuOK+bnsbeqlJDUqXOEC+O9HNdx//ljqOj2Mz3Tw5Opayhp7mVUQS0KUifKWPl7d3Eh2vJWrF+apoP3IZqbljswI7Sa9IoNa9ASCI7/9Oo3gidW13HFqMQJBhFHHQx9VsbW2m3vPHYPJoOOW51Uba2dDDzmnlrC6vJ2KVjcr9rbT41FEuwc+qOSsqWmHNEALjRYZkwPN6nqkqx5KTlBl7rgCRMpYFbws0dA/uM7sJ9hGJqq1d90jiriZMk5JLrfuhUnnwJESoAe5+ocTjtgAjd6ipBw7KhXZYcLZyO2vIJPHQP6xUL8FMo9CWhxqUff3D/UqQUl9BgNKnUyGkM9eqsp3QZ/Kyk+450sRjCxGHY0uNSf4t3f2kRhpZOFPJ3PVwlz++MZepuQ4ue/csVS1udnV2Et6jIWa9n6SokzhG3pmQSw/eWijqgxIyEuwMrswltJUO42uAa5bnM/f36vA4wvy0I8n8O72FgqT7YxNj2J9ZSc17f2cdVQaW2pdDPiD3HlqMT0ePwvGJPKTBzfSOxAgI8bCxXOyqWrr545TinliVS2FSTYSo0zMLoglzmaksrWPgUCIW1/YxsQsB7ecWEiM1UAIuPbJbVhNOlKdJp6+dAoBKUmKMrGhysUbW5uxGLTcdWpJmIl6MCA0WlXebtiqtNVLlyg5wchEZE+zsqIcnMnFaIXAsHnNrlqwJ6jgDODpQtZt+j5AfwFEUqlyKEIqopfWpHy5AarXIFPHIwrmAiD9HuSe92DTUxCVCrMu+1xbSSklBHxfOCL5ZdHj8XPDM9sHhUhgfUVXODgDfLC7ldMmpZAQZaJ56wD5iTZWlXegEXDZvBw6+3wkOQYz7MUFeP1B/vDGXn5wVBr3vKY2Ku19nUzIdPD2jmbe3NrMgC/I9ccX8O72FsZnOli6u5XGLg93nlLM2AzV1mro8nDZvBzWVnRy6bHZRBh1PLqyhli7kRn5sWyt7WbV3g6KkkeOobn6fUQYdDS5BsiJt4YrU1mxEZgNh15BQ5QsRpojobcVkTMLqdFC3hyl6KgzQnsV4ugrlPuVxalkmBlUcyw+DtInI1vLlAhKKKCU6Q7yGOshx3eExf2tQ5gjYcYlqpwZlYLc/Bx0Vqkd4MRzYcY05Vi16y1YcJv6spUcDzteVQF97OnDzOaFIpDt1xzWGb+0pEx2XATXLcrnjpd2IwRcfVw+Touetu4BbjmxkPxEG5Vtfaze18E721u489QSIs062np9vL+zhcvn5ZCbYMVq1IUlOCPNes6YlMpP/7eRTrcfm0nH3aeV8Ny6BuYUxvCjWRlUtrrZWNXJjc/uAGBbfTf//fEE/CHJXS/vZk9jL8eNTmDh6ASeWavY2KlOM5uru6hq7eOGEwqINGnxBSSTsh38b1kN8ZEmGjo9nDIxmeq2fu58aTe/Pb2U/3xYyf3nj8Nu0nHlY1uZkhvNHacUE2HUMa8knneum4FWoyE+8uCwu2XQr8wafG6ISkXkH/OJtoOwJ8D8m5GrHwKTFVG4ALntZfWi1oDInqlKb8Pfc6SOfnyTSChEnPAbNW8elQz9rpGvDy8BdtbBfoJl6x5k2XuIyed96mllfxdy5xuqGlK8CJE69nNNGb4shl/OvtZepudFs2KvyvCOyonBpNeSl2DltEkpWAzKcKY0JZJ/Lq1kV0MPMTYDPzsmm+uf2s4jP53IP84fi6v/YzoEEnYMaup/sLuNRWMSiLcbeX1LEw1dHgw6DULAa5sayUmwMjHLSbzdRFGSnb6BAJc9ujksm7tkfBKFSTam5UVjN+uZlhvNyvIO0qMtTMxycPsLuyhv7uNnx2YzKz+WCJOOiZlOYm2HaHJiGIQtDjHmlKHHw16TzbvV2KoMgTkSseiuEQmM0BkhKkl5hM+8TJE5E4oO2Sz8IcP3Je6DB9m0A3a+Btmzhnom+XPVaMj6R1TmPOGH4HdD0ihk8CglDWmyI2Oyw19AYYtV5LHl94POjJj58y8tYGLQaTlzSioTs5xoNAKnxcDbO1vwBEKkOMy43D7WlHdSmGRnXLqDZtcAeQkx/P29fVw4K4tHV9bw6MoarlmUz3Pr67GZdJw6MYWy5h4mZUdTPLjLthi1XDAzg7UVHTy7th5fUDIuIwqrUUefN8AJY5P4y9vljEl3sGewR/bG1mauWpALKMEDm0lHp9vHglEJbKt1kRVn5Y9v7uWyY7MZk+HAYtBQ2+Fh6a5WJmU5OX9mOoGg5LdnjqK910tVWz8XzMrg7W3N9Hr8RBh1aDSCJMdB3iXXb1FkFKTahR9zjSIr9baqDHpQpUoklSKPvgrqNyHf/z0UzEOkjoXEYtU7DfgQc36J3PUWJI9SP9/jcyG0esXaHYQ0RcLUi5QyX9CHGPE3/Nhi9nnZR/MuqNuIyJ6BrFiGHOiG7JkI09f3Drab9fz6tGJ+/vAW+n0BSlOiSHWaObY4nqCU5MZbyYyLQK/VMDHLyYMfVjI5y0l5Sx+7GnqIMGpp7/XR3e/nuuMLuPuVPZgNWm44oYAr5ufyj/cqyEu0cvKEZEpS7Fz+6BbGpUeR4jCTFRfBG9uUXeS509Pp9wa5dF4OXW4/VpOWydlOLAYdT66pCwdngPZeLzcvKeTNbc08trKWK+fn8OOjszDoBGnRZq5ckEdFSx/FKXb2NPbw9Jo6NEIQF2k8pCXuL4Js2QMIGHsaWJyKlOtxIbxu5LYXYaAXMfY0RGyO8jw4YvF9gD5oECa7Yp3WrEGMPhW5/hGENQZZ9q46wOdGtldAXC5CCERkshoBMUd9MiNLGqUY4EL7lUkNJoOO4kH28gvr67nxGZXVPreunl8el6+E+zc3cckx2by0qYHHVtXwjwvG097rZXONCynhntf2ML80gfxEG/e9u49fn1rMjoZe/vimkvz80cwM6rr6eXe7Eu44fXIKq8vbOHF8Eo+tqiXGZmRjlYvJ2SN7ZKnRFpaMT2JchgNvIMT8UQn85W1lUv/r00qYXxLPE2vqWF/ZxfXH53PvIEO7rrOBtBgL976zj18uymfFnjZWlHcgBNx9agmRlgMcqfocyLL3CN8oLbuVPOF7v1Vz0joTLL5LLQSgJAr1ZuTEsxFBP9IaFy5jC51BLRaZU49sl51vE0G/6iXWrld/y+ETDo40mHw+NG5X43CJJaqH3dsM9kQ1hjNYxZC+flU2Xftf9d6adWrUJ/3rG9UAFCdHcs60NDrdfv7zYRUXzsrk/Z3NmAw6nlxdx/3njSUtxkJ3v4+TJibT0evDbtJy+8lFNHR5SIg0kR1n5dqnttHao9ol3U9v58ELxzOrIIaOXh9dbqWV/8pV0+j2eLnh2Z3cfVoJSQ4zHX0+djd0Exxs+cRYjcTZDTgi1N/JpNdw0wkFuH1BfIEQiVEmfvzgRq6YrzbOf3l7H6/9YhoFiXZW7evg4oc2ht93xfxcNte42FzjIi3azKTsg8eIlj6P0tgOKG/vL2Jbi+hMZOkJ4KoHBKx7FHJmIHvbwtoFsnUPnPjHTzU1OjIgD7sS92EmDf7lIH0exdaNK4BxZ0FELNIUBSf/GZJKR5Y2o5KhvRr2LUO+fI0iFg2b7xwOYbIfMOOwvLk3/G9/UOLxB8OP9zT1EmM10t7r45Hl1WTHWjhxnOrZub1B4iKNZMVauHZRPhqNhtcHHXlA2UGmRw9d25YaFzML4slNsPLHH4wiNdpCIBSiq9/HojGJpMdYuHx+Du9sb2Z3fQ8Os44Up5l/vF+BlBAMSf705l4Kk+2sHzS69/pHfjm9gRBareC9HS1hHzYplT74Z7lrfR1Ibx+yvRLpGlSPHU7QM9qU9rZncJIvMKB0n2UIGfQrxrcjHba9rHyLNz0FniEGugwFoXEHoXd+Q2jzs8i+Dr7HV0BrGVQsU3rMe96FtiFPHGEwQ85sJZu76gFE8y7kqzcgP/gz8tUbldLf/mMTiiAUHHFq6T7wz8Ko1zIx28kza+to6RnAoBOsqejiw91t7Gvpo6ypl5c2NnLMb5dxyl9XY9BpSI+xcvfLe/j3B1Xc+dJudFqBa5gRRVuvl7rOAc68by3XPb2dmvZ+TvjzSs64bw1NLi/XLspVAkHP7uCPb+7l3Z2tdPb5+feHVTyysobdjb24Bw08xqVHsa6yi7+8Vc6zaxVJrd8XDK8LefFWYmxGNBrB7oahadUBfwhvYOh+7Bs4uMpssnoVctnfkG//Grn8H8o+FJDdTci6Tcj2CuTwYJVQgIjPR0RnwuZnVEXL51FTFPvh6R4hKHXEQSqexGf9fBs44jJo6e1DbnkeatYiRp2IRCrVmsQSCPqRva2IWZcjyz9UzyUUK5JR+dLwl0m+9zvkglsQZsdBtx6cV5rAwytqGPCHKE2JDJelDFoNM/Jj+N3rZRQn2zm6MJbtdd2cNSWFqblOrCY9eo2gpWeAilY3Ld0DFKfYWVuhhCFGpUbhtCgCVozVwFUL86hs60Ov0ZAQZWJXfQ+3nVTE8rJ25pXGc/6MdP71fgXHlMQzMz+We17fy8LRCURbDWHySazNiN2sLPGCIUmTa4CFoxNo6R5g0ZhEkqLMOCMMHFsSz0sbGsL/xzHpkXy4u5XCJPsB952ltxe54UnY9YbKjhfeisiZCeYo9VmmjgP/wMckPKOQH/xZlbzHnYH09MDA4OLW26IIYvvJSl21yLfvVKSVmrVInQlRevwBXfP/awyuU9LrBp8b0duK3PmaenKgeygDCQXUZ7G/0hGVTCh1POz7UH0+Jjsi/uAYmUzIdPLGL2fgD4ao7+wf8VqkRc/lj21BoKYmbn9xF5cck41vGOO6vLmPq4/L5Z7XytBpBLcsKcTt9fPXc8Zg1mv489vlYUb1HS/t5qJZmViM2vBExamTUvjr2+Vh3fva9n5SnGbyEu209HjDWghtvV52NfQwMTOKcelR3H5SEdnx1rCA0NgMR/hedETosQ6uHVNynBQcRJ/1UHcTuBohsRRRmqVMTvpdSK8b+eavVAVEo0MsuhMGzWaEzqTG7bobh07UuB0x/kzkyn+pz33iuZ+wej3y8H2J+ytDutuhuwmMNmTAB9teVJKOK/6pGNigvkw9zbD870hDBKRPVcPyK+6H3KNHli5kCKpWI+s2GwSUgQAAIABJREFUw/wbDup87NgMBy9dOY0ut4+QlLyyuZErF+QSZdFjM+mYkR/DqNRIfvHkNow6DdcfX8Cf3yonOsLAzScWEm01cvNzOwHFNJ2RH4Neq6E01Y4/ILlqQS75iTauenxr+Mb+69ljSIwyo9cI0mIs/OnNcoSAn8/NodE1wP3vVRAMSR5fVcstSwp5fWsTBq2GM6ak8uL6ev5w1ihe2tiI2aDl6KJY9jb1KXcgnYY//XA0Jck2pufFsLaiA5Ney7I9bdzx0m5OGp/M7acUHRhzu6dVBWdQ2fHWF9DMvxlyZirRxO5G5PrH1DhcTzMioRjZVq5EZQD57m8Qc28YeVsNJ6b4+lWw2I/uBr7HV0BcHmTNgLr1kDUDaYmCsvdBo0NueBwx9rShYw0RaqxRBkGrV9oCw6CJTkcuuAX6OpS5SeTB8xBPdirCZ6zdyL8uGMfayk6m58WQ4jRzw/EF9A0EsJp0uNx+0mMsxFgNtPf50GsFJamR5MVbGZUaRY/Hj0GruBhPrK6lpdvLRbMz8fiC7B10devo8/HkmmZuWlLI+ztamJzt5LlhI1y1Hf2EpGR3Q88IASKA3Hgrlx6bw8sb6/nPR9V0uf2MSo3kPxdNYExaFM9eNpXWngEyYiOwmXRMzYkmxm4k1nZwmO9SSsXbGZTLlXUbYezpSINFTbaYbCpAhwLIhi0j3OCEI42Qf0AF4q3Pq010bC7i5D+r6khk4hGqHjYMB5gpCyEeBIqA16WUd33OcfHAW1LKsZ93vsM+QEt3O/L9P6pepFavFmONTmVVw4Ku7O8akib0uRGRCcilf1DHbHlOKeOseRBCQcS4M5Fbn1dMVVfDJxaSA0VeoiK+rCxro7qtn6fX1BNjM3DNonyOLY7juqe3I6UqY22q6uKiWRk8tKyabXXdmPWqdDw9LwadRpARG4HTomddRReJUUay46y4+v3h4AywvrKT93a2cPMJhUzJjqbXE+D1LU00uTyMy3AwqyCWpbta8fiCbKju4rTJKYRCcOnDm5lTFMcTq2oJSsm7O1qItOjD/tW+QIj73t3Hs5dNJS1GR6zNwOI/rqCtV5WxXtvSyFULcw8sQOsMoDUMlcbsIxdt6WpURg0BL0JrVKSl1r1DBwzO4YrxP0B21iBSxiCdGUMcg8gkSJuoeqh6EyL36K9/rf8PIayxMPMS8LqRHhe8fK0qfWp0yjCjZp3S4d7xKtLViFj0K3Vf2RMh5pP2qMIa+6kykwcLEUYdc0sTmFuaAEBdh5uHPqqiedCA4uYlhZj1Wp64dAo17W4cEQZq2vuobXfziyeUHe249Chi7UZ21Kuy7z2v7eHGEwp5ZEUNF8/J4nevl9Hd7+f+d/fx6M8mIqTgkmOz+evbir9x6dxsuvv9bKhy8fb2Zq5ZlM+7O1oYnRbJ/NIEBvxBfEHJKRNTyIyN4KnVtbjcPmJsRpIdJqwmHdFWA44Iw8FxsBqO/ZyC/fC4lAjU9pegarVS4otKhfKlCGcGoDbJBP1gjUMTl0fI4lCES2MEGnviwb2+bxUH1oMWQpwMaKWUU4UQDwkhcqWU5Z9x+B8YMpz6TBz2AZqeFhWcQZWwa9bC0VcrdShz5CBxyIgwWCF5DLJyhfoja/VDf2xvH7JxGyy4XWVpax5Si4jQjMy2DjIiTHpSnWZmFeSTGGnixkErx/0jVT+fm0NVm5t3d7Zy+bxcfIEg7+9q5baTiqhs7ePPb5Wj0wh+c0YpfQN+oq12PtjVRmZcBLE2I229XrQaQU6ClWfX1eENhnh0ldLcvuH4AnQaQSAoOXliMvNL4+nu9+O0Grj+qe387JjssGl8YZKN59erzFKv1WAzDY18JUSa0A+6B1lNemYXxoUFH2YXxh64s1VUCmLBLWpMzpGCKD4u/JIMBRADLuSq/6id/eiTEQNdkD0T2Vqm+qLFi5E166Bhq5IGdaajGcYjEBaHcsDqawWDBRGVcmDX+/8QQm8GvRmadg71JUMBRRgz2dRttuBWRIRTyeoeRujo84WDM8CKve2A5EezssiJt/L6lkbqOgawDzOy0GjEiBJ4SEJ6jIW/nD2aJpeHYFBiNmi5+/RSsuNsCCE422pgel4MWiHQaODDPe2MTo0kGJJ4/UGiIwwcWxyP02rgpmd38MKGBi45Jptd9T2kRFvo9gSoaXfz0/9upKypj2OK4rjz1JKDbkwjdAYYdSLy/T8AEnJmI9ydyB2DbYrypYiZP4eMyZBYgmzcoVpEAa/KtIsXKeOM/k7orEWGgt+xe+qAMujZDKlrvoMylPpEgBZCzAHcQPMXnfDwD9BG68gMKzoTkTkFvH2IpFKlv2yKVAt87izEpPNUEDZYlPzn9pdVvyttAvLlawCUM0/bPtXfjM48ZJdekGjjnOnp7GnqRa/T4PEFeXJ1LdcuzmdVeQedfd6w3vWu+h6uW5zPxqouTp+cwqMrawEIhCQPflTFVQty6XJ7KUy2s6m6i7tPL6HX46er38/Dy2uYUxTPw8tr2FanerGNXR4e+NF4VpR34PYGeHh5NXedWsKysnYKk+z0+4JMynQwNS+GwiQbhUl2WroHKEqy8bdzxnD/+xXE2IxcvSAvbGtpNmi5akEuRxfGEghJxmY4DjhACyEUsS+xOMz4DaOnWY2+yRD0DSArlkPmdAj5YNblCL1ZBYy37lTVlYJ5EJv7yd9hiQLLpzvxfI+vgMhEpRcQCgzek37YuxRYCu6TPnMG+ttEnN1EbryV8hYlwTkhc2gMERQ35KFlVVwxPxeLQUu/L0hVm5u/njOGfc19tPR4uXphHkadljP/vha7WcfZ09JIdJg4Ks+pvr9AtNVIl9tHs8vLTx7awA+PSue+9yrYWNVFskOV2XMTrLi9AdZVdlKSYqe+y8Mrm1RPd+Xedv569hjKmtR1vr+rlbMaug+Nc1zaJMSJvwO/Fxwpymt9OAwWRMZk5fm94fEhMaDNzyjpZIsDXrtZ3ZcWp5qqOIjtim8Vn1/ijhFCbBj2+AEp5QPDHkcA+3toncC4j59ACGEAbgFOQplOfS4O/wDtSEMc9yuVGTvSEOmT1UJusqsfZ7pi6hbOR2h1SEMEoqNKCSjMugJRMFd90V69MdyLlNtfQSz+tdpNfgqk3ws6Q/jm+6po6R7g8ZU1rNrXwbnTMzh+TCKBEPz3xxMpb+klL8HK8WMSufm5HeH3BEKS9BgL1y8uINVpGaHNnRRlpn8ggE6r5ZqnlDLWixsbeOiiCVhNei6bm4NBL/jD60Olq3Omp3PNU9uoaHWTFGXizlNLsBp1LB6TQKRZz8ryDq5emMfmWjXGEWM14LQacPX7SIwy8+jPJqEVGrSakX+DhCgzCw5S2U32NCObdqpNmDMDbLEjg7Tfywi5BKGBCAe8/3uwJSCPvlKxSk+7TwUOW9zX/sy+x5dAbI4SMeltVZvipX9Uz6eMVeONDdvUBvoAZpsPNpIcZv5+/ljW7uuk3xdkVXk7Vy3Iw+0NsHJvOzvre+jxBLj/vQoum5dDnN2I2xvklU2NnDIxham50TywtIIBfxB/MER7r49/Lq1kTHoUp09KBdT9/tGeVhq7BkiLtjDgD2Ez69hYpaYjGro8dLi9xNmVeuB5M9JZXtY+gtDW4wl8Inc7VAYZQqcfsZGVsXmQOkFJIKdPhNg89YJGCxHDRqZ0RuiqQyCGKin9ner78J0I0F9Y4m6XUk74nNf7GCpbW/n0KanrgfullK4vs1Yd9gFaCKHUjRI+m/Ep+13QsEU5HOnNMPsqxNQfIz09yO41qgc5fOGPy4XOGkLtFQiLA7lf/CIUhMoVSvEoqRRKT/habiyr9rZz33sVAGyq3sJzl09VveDCWGYVDvXfLpqdxfK9HXT3+zlvejqufj/+YJAnVtVw33ljefDDKuxmPTPyY0h0mNlSM6TqJCXsa3Xz65cVmeuuU4s5b0YGv3l1D4FgCKfVQEWrYpV2e/zoNII3tzYxtzSB93a2Mrswhlc2N/HEapWpZ8RYOHliMh/ubiM/0UYgJMlLsBFzsMgpfW2KxGe0gTNdtR2W3ad24AYLrH8UmTUdio8Lqw9Jb6/qc257UVVBxp6uPJ7HnQFGO1gc4HVD215kdyPCman6z1HfhcXi8IMQGrWwx+aqsZzEIjUXG5WifNZBVa3Gn4XQH3rlqy+LnHgbCZFmml0eFo5OIMVpYeXedi5/dAtXDs4jd/T5+P3rZdx77thwLxqgKNnO+7vaaHQNcMW8XO59dx92s45blhRiHOSLLC9ro7nbS017P6NSI4m1GTHqRq7N0YNz0TqthtMnpzImzUFrzwDbarcQCEnOnZ5OdpyVi2ZnsmxPG6dPTqX0AJzhvgjS74Xa9crPIHU8TLsYIUNIIVRgBmgpQ2RMRsoA9HchsmeqtXH6xUMn0pvUPfydwQGVuDeiytprgNFA2acccywwRwhxKTBGCPEfKeVFn3XCwz5AfxxyoEeVXEyR4QxYdDeo4Azg9yB3vApjTlUjHfuWKVvKhbcpt5aIGETWdCVbF/QpBvjUC1U/U6tXQQOUxrczA/K+Oqmotdc74vH+mciPY1RaFE9eMpkut48ddd38+pU9/GJhHjqNhg2VXfzgqDT8wRA763tYV9nJ0YVx4f5wVmwErkEbO18gxNvbWwgEQtxzRimRFj2hkCrf2S06LpubyxOraom2Ganr6GdCpgOTTsvG6q7wtVS395MRE0GKw8JtL+ykdyDAnKI47j69hDj7AY5S9bYi37tHCSNoDYjjfgURTmjehZh4thrzADXDHJ1BqKsOOqoQeXPUZ5kxVQkqBAYQMZmKZBSZgLDGEtr6Iqx7WP0ecxRM/xn0NIDBCjFZRz6r9DCFMNlh6kXI3lZ49zdDL+x4DYoXqYX7MILVpCMnYSiz7+jz4guE2NnQwyXHZFPT7uaUSYq0NSM/hp31PVw8J4s4uxEhYHdjL4mRRiWnGwyFxwullPR5A2Fi5fu7WnngR+No6PRwy4mFvL6liRn5sUzMGgpiNpOe8ZkOgiHJq7+YjscXJDPWQqTFwHWLC7hsXg5Wo+7QVoPa9ykSLSiFN1u84u18+Gek0MLsK5Af/g3cbUq609OFbNyBKFmEbNmLWHCrGoOMzUF8gzajhxQH7mb1ErBcCJEELATOFELcJaW8OfwrpJy5/99CiA8/LzjDERagpase+cFf1BzluDOhaKESS9AZ1Jdrv5a2OQoRGEB2ViOOux3Z04KIy0PMvV6dp3bDiIF62dsKvn5EYtHI3zfQ85WsJ/djdmEcDy+vprnby+yCWHLjP910o6V7gFuf38n0vBj+8nY5l83L4Q9vlIVnLk+fnEJpaiQPLavm4qOzuP6Z7fz0mCysRh15CVZ+8tCm8LnSoi0kRBl5dGUNm6pdSpTkgrG0dHu56+Xd9A9jfRen2Nlc4+LE8UlhU4Bji+PocvvYVtcdJogt3dVKZav7gAM0Pc0qOIPaFFWvQYw7E/LmDH1m+9Hvgg2PAygpwSkXqCzZaEU60tDYE0Ye37B16N8eF6KvDbn6PwCIo6+CnFkHdu3f4zMhLA7Qm5BxeUoZDBRzW29CevvUpsoYqUqqhxmKku0kRCo97ZIUO38/bxyp0Uqy9u/njaXfF8RhMSCl5N8/msD7O1uYmhvNBf9WznITMh3ce+5Y4iNNdPUNfYf7BgJ0uf3MLIjFH5ScOjEZm/nTW2lajSA/0faJ5w6m4cxnwjtkG4vepCZj3v+9cjEDlajkzILeJuVfYItX7cTVD6qM+cTfo0n9RIv1yMcBBGgpZY8QYjYwF/idlLIZ2Po5x8/+onMeWQG67D1oV6MMrH9EKU7F5yOdmYjZV6lSqCUaUTgfuepf0FWHrFiByDwKWbUaaU9AE52pvmxGm/oyCo0yXrDGgj1ZSQ/WrFNOSEmlyKZdyozB8eV3ifmJNp69bCo9ngBxdiPRn1Emrm53MyHTQUmKHUeEEgzZH5wBatr7WTwmEZtJR8eg3CAINla7sJn03HfeWF7a2Eiq00xhsh2PN8CmalUGr+/0UN3eT2mqfURwbuvxYjFoqWrvZ3ymg39fOB6PL8i4dAdba10kDesvazUi7Cl9QDDZRmyghDNdbawm/FCNcMTlK8WqhGKkdtji1FKmPLqX3acqHGkTCU06D41jiDUqCuYiG7aoB7F5yOF+tbvfhqzp38t8HkIIvRmm/AiZNAqCfkTG5MH2xd9VFWr0yVC86Etr239TyIm38eSlU2jt8RIfaSI12kKzy8O+lj4iTDqKkuzoB8vUc4rjmFMcx+WPbCY4aOy8oaqLhi4P8ZEm5hTF8dCyKtzeIHkJVkpS7MQe6Kb2UMOZrgiyMTlgjYHmnYgJP0CufVhtrBKKlfFFV526PzOmwId/UTye4uMUb+Q7BwkHaJgrpexiiMl9wDiiAjRCo8wTIpzQsgeEQAYDaPRGyDoKmVQKHhdyzX9VGdvrRsRkDSlJ2RMJzfklmthsWPxr5X6lMyMNFkRMllpEZv5cqeoALL8P2bpXKVwtukMZbXxJJDstfJ6lfVlTLxf+ewP9viBWo46/nD2GfS3KgeqNrc3oNIK5JfHUtLu54fgCvIEQWbER/OpF5df66uZGHrxoAhfMSOeBDypp6hpgRsFIDVy7Wc+/P6zinOlpPLqiFrNBy0+PyWJTTRcbqrp4fFUt4zOiuHFJIUlOM0lOMyWpdrRawZYaF+dOTyc5ykR9Rz9REXqsX3dn78xQRL+q1arXnzoeUBmYsDiQ825E+voU0cujvIUJeKFoviIH+gdtJGvXI5JGIwNe5TZmi4O0iYjj74b+LqTFCe//Yej3JhR/H5y/AQh7AqJkcfhxaNMz0DzIDN7wOERnIVPHIYRAerqVn7Ah4jMFgmRfGwz0KmOUQ8i+T4+JID1GjeS193q54ZkdfLSnDYDfnlHKnKJYYoa5SI3LiOK1wakLm0lH1KCy3+j0KF644ig6+nykOM2kOA+vzcinQdgTYMGtarxq45PAYIto1Emw5y1E+iSlfw/QVYtIHg1zfgFanSICflfvq+/drA4AWdNVubSrTpljuOph9YMw+iRIHY/GZCPkcYHFoXSZ4woU6WG/klRPE6KnEWKzVd9ksHcyvIwt9rPD67eq4AxqbKtm3VcK0F+Etp6BcGbb5w2wvrKDM6amMrswlvxEGwmRJno9frbU9jAtN5px6ZGsrRjqGUsJFS1u7nxpF1cvzOOFDQ0YdUpgf+XedkpSIklxmKho6cM9EOTKBbmY9VqaXB4ijHrKmlQpa2O1i5V7O7CadOTG20iNjuDyeYo4U9fh5tJHNrOuopOTJ6ZwzXF5XyszUES/IqXH/CmQoaCyBa1eC5lTYcFtCJ9bLeZ9rUMHanRgi0W+egOYbIgpPwJrHDjT1blr1qkZT3c7wmhDpoz5ytf6PQ4BOqvUPWmOQq74hxKNMUfBcbeHxTD2Q3bVKblJd7uS6p19hRI3OcRQTOy28OPnB53lFo4eEuJYNCYRu1lPTUc/xxbHkRVnpbbdzYd72giFJEcXxh0RwTkMk10lOvvhcSFSRkPB3KFK5SBkwIcm+//B/fS9WcYBoG4TVK1S+sqrHkD0d0FrGfK930FnDQBioBv2vq+O76hE2Ift0rUGMH06M1IG/ciWMmTtBmRPC5isSrZwEJ9nRP91kOK0kDg446jVCPISbcz97XIeW1mLQSt4dXMTd7+6h9YeL67BQB1jM4R37UkOE1ERek6dlMpz6+o5piiOxCgjxck2zp+ZwZziWN7Y0sR954yjuXuA1zY3YTZo+dfSShyWkZmwXivo6f8kkW3Nvk7W7OskJJUz186Gnk8ccyCQrgZCK/6FqN+s+lx9rbD9ZYSrDvraEHoDOFIV4S9lnFKsKv9IqViNPhn54V+VAcqW55E+NyQUqeqK3qQ2BIdwxv17jIR0d6h7p3E7ZB2lKl16CxQvUm2i/g5w1angDKrSVbXmk+dp3KaCM0DTjvB9fahht+iJsQ31igsS7ayv7BxxTKzdxMkTU7hqQR6lqVH0Dfj51Yu7uP2FXdzx0m5ufHY7Pf3+j5/6sIXQaBHFiwinKKkTwJ6AiHBCdBakTVBroDMDkVDwuef6bmBwzOqzfr4FHFkZ9MDwACGHMmMZGhqmH65kFPQhhQ4x+XykpxuRWIyMyfkE8UsGfMpQo32fyry2vaxmqBfepsQxYnMg+XMlU78yMmIjePSnk6hsdWPUa/jVi7uUXvbqWu45o3RQ8QiWl7UzMctJlMXAH97Yy/kzMshLsLKjoYebnt2BLxDilhMLGZ/h4JGVNTy5WvVg05wWfn9WKdF2A49cPImqNjeVLb3cfXopdR39XHx0FsvK2jgqN4bufj8pzk/ONuu1I/dvH5+JPhDIgBe55iFE6ng1SzkcA93IrS8gZl2h+l65RyMK5ikyn04P8Xnqc9lP9Nv6gvIWjs6ArGkIph206/weXww50KN08fcH3yk/UiTOhi2KxOfuAFuickBSCuvquE8ZYRSmyJGDLt9Q7zrVaeE/F03g1Y2N2Mx6mlwe5o9K+Nz3uAeCIyYhNte4cHsD2C2HHynuM5E2AbHkHvB5kI4UcDUQ2vQMIm0ipI5HZExFOjNU209n/Fpjp0cMJIddBn1EBWiRNwdZtUrtsAvmqwUbFNtwf4brTEfM/Dly20vKr7a3CVmzETHlPJACjdGibO5ayyDgQ2r0CL0R+c6vAZBag3LHcrchkkd9zKD+4CIrzkpWnJVttS6qBp1wVAtkZCCMsxvo7fdR3+XBGwjR7Qnw7Np6ipLtVLW5Mem1xNoM5MZbuWZRHk+truPcGen85rUyGjo93LikgIWjEoi2GTjxz6vwBULkxFu5ZlE+8XYjcXbjp7pSTcp2cvLEZFaUtXP65FRKUg6iLGrAD1IqI3hrjMq4WnZDyljFAPYPqA1YwAt73lH95ZzZqjTqqoOeYa46etNIn+LvEAZF9Z+TUs74tq/lM+HpGQrOoMw0EgoR9kQlGWlxqvsz6Ecc80vV90wsQaSNQ3q61Warfgsifw4yvgAm/BDqNytluOhP6nkfKoxKjSLOZqSqzU2EKZbCL3CQiorQc/7MDP42qMF9/owMoiIO7+AsfR5o26uSHWcGwpGqDFEAOqqQb9wGubPV6GNnldosZc9Qa61GC3OuRkQcqX7PXwLfB+ivDxGdAUvuUaQhiwMG+qDkeIiIDqsXCZ0RmXcMImMK0tWAaNiCzJiM3PGGysJ8/ch1j6oZaYC8Y5VDz34EfSowmOzIwAC0lqt5P2c6YtA672CjIMnGveeO5d8fVLJodCJOq57L52YTGWHAoNUwKjVqUO4zj/8tq+aaRfmcOSWV7fXd/HROFmPTI/lgTxvBkFIk+sNZo3h4RU1Y2OQXj2+lINGOy+3HN+gxu6+lj5V727n95OLPvK4kh5k7Tymhz+sn0qwPS34eDAiTFUoWKyWxrc9D9gxE8lnIhCL44A+DjGxlDi8mn4fs70bs+xDZ36lsCm0JajTE40KMPlnpsn/HIIRwAA+jJAQPXxgjICoNXEr0huTR0N2E3P2Wejztp2iEUOOQWdOQKeMQbeXIPe8jbHEwOBYn6zYgjv8NYuxpyNEnfytEpIQoMwlfUinPqNdywYxMJmc5kUBhkh2z4fBdUmUoqDTsd70BNetVBWPxXYowBoqYFwogrLFqYmY/WstV+6h8qXIV/M4G6AMzyzgUOHy/TZ+BESUWw6evW0IINQZgjkIGg4rJHfRBwIN0d0LliqGDa9aq3uZ+v2GjErgAoLkM+eZtAEidEU747SHpaxp0Wo4bncixRXFsrevmkv9t4qdzsrjzJWUSMjnbyT1nlLK6opPm7gE6+rzc+67atX+4u42iZDttPT5+97qaad5W6xqhkR2SEAyFSI+xMDY9is01Lgw6DceN+WInGrNBi/kQSQ6SPFqNu/n71Y0fa1HBetYVCF8/0hYHIYlsr0bY45EbnwBA7n0fMftKRPFi5IYnke/crTZqo09CfMZ34ghFEDgDePnbvpDPg7A4YN51yPqtCK0BaY9Xym85M9T9FDuSXCk6q1WmpjMiixaOPJlPVZKOFJZwpEXP1NzDP2DJgE9ZtG58EmzxSiBo/aODzmODAToyUanEtVeo/nPtoOx0+kTVrtDovqPjVcPwXQjQR0TZDRRBLLEI+fZdyt8UYMGtSvqzerU6KHU8Uh+BWHAb9LUoW72lf1IMx0nnDp0s4FW90kNIPDLotbi9AfITbLy3c4i9vLaik56BAAl2I3qtoPtjRJTOPh+1ne7w4/WVXTz6s0nsaeqlyTXALScWkhUbgcmg477zxlLT3k+URf8JkYRvGkKjBUsUsrVcqbhtfFL1+3e8hoxMRHhcSFscwpGKrB8SZSHoV97gG5+EhsHntzwHmUcNba6OQAgh/gXkD3tqqZTyjs9TlBJC/AT4CUBa2reo6GSIgMqVyJbdapEbezqMP1NlZQPdhIJ+RH/HoPGJcpQiMICIcCL3u9LF5qq21Pc4+OiqQy67V/3b3Y60xUNiqapEDkJYY+HYa6GnRXkaFC5Uo6z+ASXkdNRP1Pz0dxlH+pjVEVN22w9P9xCZDKB5F0w8G5E1DUJBZE8TvP0rZGKJmrNuHNTh9bkRetOwzNqmRnoOMSItemYVxhJrM+ILhNhc4yLWZiTKoifVaeGuU0vQ6zRhu8mceCstPV4Wj07ipfWNDARCJESaSIg08exlU/D6JbF2Q7g8nRhlPvgeswcCrQEx5lTkrjcgdSwiNlfZR/Z3IfebyscXKsGLyhUqOMdkq93+8GqKVq9+jmBIKS/+4qM+8Z4HgAcAJkyY8O2tLgN9Q7PPANVrkLlHK5JfaxkkjUJGZyqW/twbwkJBcssLMO9mBFKJDFm/wySkbxPDlcMAhEDMvHSovL3/6UG/brUlVMmIAMXM/65DSpDBLz7uG8TXyaCPiLLbfsioZKUS1temxnNissFVj8hrQi7qAAAgAElEQVSejqxcpfSfAboboHjxUICOSkNGpSCO/40qA0UmKULF/vMGvEqF7CAGhfLmXs7/1/qw1OZfzh7N4jGJHJUXE56vPG2yuoY0p5mV5R24+v38/vUyJmQ6ePHKo6jv8pAVZw0LMBz2aCtHfvAnRVSJiFU96chkqN88dEzLHoTRqnzAe1qQcblqIRl9kird9TQiJvwQvlO+tEcYTDY1t9w06NCWPQO66lVwBmjcpqYoANm8W1lTujsUgcwchbAd+lnn7xKkx6WSD6NNVSEG+lSryGhTKn0fPz4woNa3XW+ANQ7xf+2dd3hU55X/P2dGfdQrqggJAab3bopNMcW4Jk5iJ07ZdbIpTrzJbuLY6XbaJuv0bJLNpu4vXnu9sRM7bnHFNmDAYMD0jgB1oS6NpDm/P86MRiMJIYEASdzP8/AgiTszV8Pce973lO939OJuwdmBobeDHsxpN21tBvX1KiPoShuNb8lnkNrTEBaFbvgNzLjNhj1ikpCZd6AttbD7aVs5rv6arTZTCjpWk91et+wAuuFXNtI17yMDVpcurWnuCM4AB0rq+ezqsT0eGx0Rxo+eO9ghPQjKqHQPY8/ReXo50NrTJhkYGdfdwKLNa415p3fZnxX32YIoOsHS1gAjZ6F1pUhTLbr3GStFZE4wD9qlnwZfO+IOt9Gt41uswSV7KjJ6CRIz/JrHBiMSnQCL7zaBi7BISC2CkndCR6ZcYRbE0wpNCrSt2R675B6IczTT+4rWlaOv/NCul8Q8WPoZdNNvzNd5zLUw833WF9AJiYy1BrGpt9r9LSwS9Tb1GMyvXIZgk9hgTbtp5VGbvWxtggV3IZndu5G1/CC67VHIn4vuec7GC+IzkYyxNspzdBO683FzuFrxRTQhF4nrveFDG6rR501aEkBf+RGs+Ybt8C6QrKRoUmMjqKj3IgJzCs+e7isaEctDt0/h/v/dRbIngvtvGD+gXdYDhdaXo899ywxOAFn2BRg11/6tqQaNiPE3pGyFjHFmaxcWjiblIbPuAPWh9RVQW4LWVyJjlqEJOWhdObjcJqoQmNeuOIy+8G/2dfE2iEuzuvQQpy+i+oMBiUs3+VU/mjHOpCOPbYLCRdYfULIb3nnKOvO3/LcFC1+b2YUOC0/hS0Dl4WCm4sxxtGSPBWf1wb7nTTc7b0boY9KKzLq16jgyYrzdF5uqYeE/XbTplCHJUAvQgxFtbTLJQH/6TJ99AG75UUeaTL1NUH0MSvaYElHxdpj/D8iCj0J0gpnLl+6FnY/bEzZUoMc241owzRSpSvejjZVIWhHStSnC12buSgGa66C9ZzvJ/lKQHst/f3wOB0vrSYuPZHIvfrBhbherpmQya1QyYWFCSuwgnQOuK+sIzgB66FVk1FxUFcr2IxWH0BETkYxxaEwKuNzoG7+EMdeipfugbK+N0U17N3rkdbRoMVJfhj76CWtMWnFvUILV2xDy0tpQfV5uZA4Dg8QkwazbYcotqNuNPvdtOGXmPlp9wryj60rRxiobtbr2X8x8w6F3ulh5SkQ02jmw9NABL2ER5nGfmIM+/jkrL4CVl9Z9CzmLwuKVhaLDoAZ9+fG1h96M27wdxX1tbUJ3PQFbH7aa89wPgyvMdtMxSRagwdJtnVWNAjvgsoNQvt8axN78A8z7cOjK3pNsQigv/8Bq0As/NqAzuEUj4iga0bfuardLyEgc3K45qmrvT1ON/SBzov1dshvd/EdbxaeMQmNSkLgMNCnPREp2PgHjViIzbjMJ1g2/hnavBfQ3f2cr3SYv+vovYe2DSHikdQAHnLGik5CsiZfvFx/CaF2ZX6NZYMS4C9LCFleYyeZ6G9GmoOoW3kYktRCtPY243NZL0NoCToA+N6mjYd4/wIGXIG+m2X2OXmyqbeOWWxOlH60rs2slNs2mJrTdrq8A3ia0tQVKN5uSYtZkyBg3ZMbcBp4hVoM+G5cz7SaRsbDgo+izD9pNe/HdpkYFtjLc6m/88rWhe5+HtNFISj76xn+a9+niuyEpD1nyaXTbI6aoU7QUrStDX/sZ1JXa68y83VSSOgVocbnRgvnWbCYuiM+4uMbqQ53Kw8iUW8xbOzIWDTTaNVRBSj54ZkJzDZJaYCnu9jaTZt34X3DwZTR/LrzzZFDWU9vtfQ/sGMIiwP/+S1y6jYk0VkFkfKgOu0OfUG+jvfdH/TrZBQvh6k9ccK1SImJg1h1WgvCkIrPvtMWZtwHd/Edk2eet0czh3IgLyZ2BjpyDK5A1XPhxaxKLiO3w39ZTO00hMSwGWfxJyw7GpsPSz8HzD3Z0clNbGlRS3PYosu7bQXWxKwlH6nPgkKxJcOuP/KvDVFupgzVuRcYGxwri0iFzogVev163vv4f1gw2ejGSNxPCIkxgoXRfR3AG0LL9SNE13V/bFRaUFu0nWluCHt1kC4tR8wfchONyojX+ZrDoeEgpRMLCkfQx6JP3279HxSFrHkDPFKOv/TS4kp90AySNBHcUHHgGrTqGLPsC2tYERzYiM95nu2YRNCoBmfsh9O0/m2XhvH+09J0f8aT0qPHs0Ee8DaEd9MXbwNsIA9BMpMe3ItPfC54kC9TaDkVL/YI1sVfwrq3vaEu9jabt+D/TAlj1FSRttGWQwiNDj3v9F9DajEx/L/r379j9T1xmz/qunwACceno7qc7vYAPms5c+l9sUKDgcwL0gCFx3eeSJS4drvsK+tbDEBGDJI1EwyJC68RtLaDaoTimZ07iK3kH4rMgczKctlErGTm7Yy5TG6uhbL/VoNOKur22trag6kOqj9uHPCkPifR0OaYZ3fgba5oBc/NZ9WXrgB3iaF2Z9QLUnAQEWXmfNX+lj7EVedMZa9BLzLaFUOc0W12p/cwdbv7BgB5+DVn0KUjIQJvrrLs7MhZprEKjcmHdd5DwCCTS2XUNKJGxULQE9jxr3xctsRT1QNDuNSGTxurgvOmBl6yL2xEo6Rs1py04g82R73wCueaz3Y8Tl7mJgXXLB8yE1IdWF+PK6OROlVZkSoltLba4TRg+m4Z+4+ygLwHxI2zU40yxCfEnZFvd+LWfQVgUMvuDcGqXpVsjPOj+l6ClFnY8YR2Qk9ch4u5I82hbq+3Ydv3Fnj9nGiz9LBIVa/PQh98wcY2UUR1ylEx/j0lPdh4pam2C8gPB76uO+EdNhn6Apr7CH5wBFD2yAcmbiYjL1ME6E5du72HxNusTKFiAHtlgF0fREjjwsh3nazPRfjDpyHXfsee8RL/SlYiER9tnN28WIOadPkBGJDLlZnTXXy3LFfAbjoxD00bjctLbfcMdHlriiU7q8TCJiIGr/8maaaMS7D1v99oOukvWTtKL0Bu/Z82v0YlIwhU8H+0E6EuAO8yakiqP2PfeejRrCvKun6K1py291lJvwhZL/xmJjEHf9s/cvv1/SOaXkNxO9pKtjUFpULDA0lSNusNMaOOVH8L4VbD7qeAxh9+w+d2wSPNYdYVZjW3SDbDpN3bMxOvP6k89mNA2L5wptuxBYm7P9cjoBBgxEcmfbQuRtLPXsCQmCRZ9CioPAYK+9ShStMgsQXNnojWloK1o51DcXAstdcC59cMdLgyJSbLsx0A/b1IuzPmgjc3FpUNDJTJxLUTFof6MlrbUW106LArxtUJYdLdM1BVNUi6y/Asmc5uYg3TVMu+EpIyC1V9D2302SlVzEuIyui2YtbnOeg72vwC5M9EpNw1vW8mzooAToC86Eh4NCz9mc5beRmT2B5DYZAB0w38G69Ph0VBxKCgRmZyPjFtuA/3ucEgfZw0XER5rltnxZzsuZ5rNE55+B03IBsSanhJybGEQl46MW4Y+/i92PkvvQUfNtyA9bgWkF1mtI3kkEj7Yu7B9prH8yo8AhVl3wMTru+2qJDEbJq8z4wowLfM1D0BSjqU03WEhoxziSQZPMlq83cauNv3OUqCArPySaZ6XH/AHaTWdZk8K2t4KpfvQ6uPmbpY+Jth/4DAo0cYz6MGXoeQdZOxyJGeazUHXlVudtKYYmXk7vvSxsOm3FiyypqCpBVBxGBZ+1FG98iMuN4ycbSNT7vBeP/uqaroCvnYruZ1t3rniYEdpiXeehBFXQcEV6KmuODXoS4Uk5VpHr2po80neLDj2ph0zaj66/qfo1Z+wG33B1egbvwJAeQS5/kGzWasvR7KnoJkTkbYWVNzwwncseM26w0w13vwdMudDaOZ4SMqz8R9/ukRf+w9kxHir74jLAv55OsNo1TFrXotJsgXEQNUHz0ZznS10AuMHW/4fFFwNPXRIa8keC6QuyyxQfRxqT6N7n0dypqKeVMgYG6pylJhjs+qBLm1MecyVNwONnGb1a2+97dw9KWjJbvSpLwGKisukWDN6VltzGCQUb7fAC+ixLcgN34X0InTHn+GEOSbpSw8hSz5jfu8AJ7chmVehJ7dZc9nENTYqufMJiElGrroOSehbNkVbm0zzfRA0oWlznW0QIj1I1Pmr/vU2L66qdu3VnEZf+r7p18//Rxi7PKShsoP2UPOdjnr1FYezg76kiLjoWrCU/LkWIKuPowlZVqte/1MYc42lxjtQaKhCq46bNV5TtTm/zP1wxygQrc3osc0w472w6qsoYrO33no0Kt6fksXS2K4wk6Lc87TdrNzhyIr7IGdqn38frT3tP5czFi4XfRIZu+yC3qNzEhZhHetNZ2DS9UhkPNrW0mMdWHKnmaxnWzMy/x/B50P3P2fSjn7PX0bNN/WigH93bKoZlfjNExC3jbDhF1foGnzryulYLKgPGioIVaJ1GGxofVnn72zBBaFaBuqzxWsI/u9b6vD5dQ04tN4ObzwDS+7uNehqeysc22yqWSn5MP22y7oT17pyqwkXvwVZk2HRJ5C4gRsF1JYGqC+3vph9L5geQCD4vvErSBuNr/KYvQfpY63zG2xueuQca15NH2s76CsVpwZ9eZGoODRvpo2NlB9ArvmcdXw3VEFhlnU+tjZaEA/s7gICC43VUFeKKNYMpj5rqKkvt9r1zNv9r5EA137OOrZRZM6HkOgE9Exxx06C9lZL62aM7bt6UlNN6AhE8Ta4yAFawqNh/l1QeQTd/HsTPtj1JLr6q6HmIa3N6LbHgkpRlUfM3GL8Ctt1g+1ikvPh5NtoRIzVGVPykbRCWPuA3ww+pXfLyMScYMNLeHTIjLrD4ETyZlpzWEsdjBhvC2NVZPKN6KldNrc+YQ1aXw7jV1u/R850tLESRoy3IsdbD1v2K2DIceaEBZ/edsXVJ9AXv2fXadURNC4DmfGeS/Z7d6PigAVnMFOesgNWEx4AtKXe6tLvPGXjhwvusoVR9TE7IMKDHt8K2x6xMtJ1XwF/n414UmDxJ6H5TnvsMJgqOW+cAH35kbAIyJmG5ExDK46AJxVam9AXv48svccCdNwIEzdprg19sCfVAmvgP/Ltx6zRrGgJuu8FkwZNyrUGjeu+bK8X2Jm7w4MLADBxFVc/3LBiUixAnSm25y1YeCFvQ5+RxGy06qjJdgI0Vlpt0B+gtbXFUncN5cEHNdUi4dH285QCqDpmXbx7nrEbsrhMYKauBJ8qkjEW8Wt093ouaYWw7tvWNR6XbnVoh0GNpBbADd+F5lrb3b34EJqUAxPWIks+bZ9ndzi6+Q+QPg7WftN6GOrLYdv/WHAGqD1tvQniQma859z9G+3e0BtuQM3uctH1Wu+jE556G61O7G2ElFE977prTltwBmuyO/QaMmYp6nJDS71dewE/aECrjoQ0wkpknGWxrmTUmYMefLTUWWonOR+ZdgvUl0Gb124Wq78B6UXIss+jJ7ZaoDpTDJ7k4K46JgVO70aPvwkz3ou2twbTv7Wn0ZLddrPJGG8X1qovm8RlVDwy833B4N0HJC7N5oGrj0FkPKT1stMcILSh0n73rqM20VY/05rTlilwhyPTbrOOdvXB3A+iTTVw5HUb3Zj+HrMWbKzyP7HPgv6Bly1lH58Ja77eJ1lJSS3ofZftMChQ9VmjX8VhJCHbNKSf/prNQJfthfBo2zUf3QjhUaa3vvd5JCIGifSg4kLjAilpQcavQsWNjF2G+nfWvZKQDRPWWOCKTkSuWtH3c688ah7lER5k3PKBMfJIGwNTbjFf8/y5fVbr0sOvWxkOrMdj+b3WZNmZsAgrAfj8eg9xGShukwUt328d3OLPNogL6TwH7eDnwv2gReTXwHjgKVV9oId/TwAeBtxAA3Cbqnq7HhfACdCJ2ZA7C8me1JGSJm6E+dnWV1gjyqh5kJwPFYeQ+Cwb7N//otkcjrkG3fEXZPxqdP1Pzexh+b2QkIU+/XVoKLeK6ew7kSk32YWx6qvgclmNvJ9IQib0tTnG1w7qO2/PalWF0n1IY7XdGGd9AK06jOTODM6I738BTm5HZr0f3faIBeLwaHTkbKS+HI1OhN1Po+4Ic6cKpKcBiU23HTbY7qi5rkd7T4chSsUR9K/32Tw7INd9KfQG2FAR9PBubba095LPdKRYJSIapt4C+XOg6rgpXlUdQV1hyK0/Omd5Q6LiYOb74KrrbAHQx8+WNlSZ6E5DhX1fcwqu+WzPDVb9QGISYMZ7bNQyIqbHxblWH7emuKgEyJlsc84HXgoeUH7AylxdArS2NpnC3sFXbfxq4lqbenjyL1C2Hy3dg0y91e5tcRnOAvdsXIAftIjcDLhVdZ6I/JeIFKnqgS6H3Q78u6o+LyI/B64D/nK257ziA3Sg/qKb/0BH81FdCRLuAY91G2tTjWnVxo+AwsWm9R2XBhNWo0c3wqQ16Ks/sZpYe6t53a64NzTle3wrvsIliIB4ehYXGEi0+ril4lsaYO4Hz2/FXLrHTEHavZAxDk0bg0y7LaT2jLcR4jNNIarmZIdQi6QWop4UGDUfSR+LNtehyXkmGFN9AkkeiYbHmDBJ6R5Lr8Vc/PfF4RLSWBHc0QHqjjBTh4OvmCrc6CVooD8hLAqyp4SMAqn6/N7ShfZZrvLrGvja7U/guOY6W4j2UDuVCI/1k/SHtpaO4AxYR3R7i+1SO59b5VForjGFvHM0n2l7K+IOt8VydM8LZq2vQJ/+RnBRP/kmXHPuREfOMZtOgPhMy8h1flxjtfnZJ+bahuHkDstoucNh5h222GhtRn0+JG+G4xjWG75ed9CpIrKl0/e/9FsrB1gCPOL/+jlgIRASoFX1Z52+TQM6d1B244oP0OA3m8+ahO77u/0gwgNZkxH/6l7bvcjsO9F3noQ3fwuTbrT53r9/10Q5IuPsRhIYTwiPslpzwFkJkMIF6F//FfW1wfIvIulF3c5D21qstuttsBnp89xNamsL+vqv4PRO+/7ZB+Dmh0KeT6uLoa3ZhFR87UjVUbT8ADJyDmROMFOQg68Ex59K91pqMdITklqUq1aaTGdSLvjvn0R47CZScQiOb7EZ2OgEZOHHLeC7w9GJ18OZk3bMhNWQP7ebybzDECcu066N1iYzQDm+BUYvQUYvRsOj0IRs5OqPQV0FJGZb6cKP1pyypqe6Mmu+nPcReObrVk9d+E+2EwS07IB/EdlqUw3Zky/8vGOSYNq7YNujgFhjWUSXccbSvehTX7YFSEI2XPelkCDdIbzSWG2GPSe2mgZCwfyzB0hvQ+ii/tROfM31kDsdic9AvY1I+hgkYAwUeK32VpMs3vJHa8Rc+E90jK9kTUJufsjen7gMJzj3huq5AnSFqvam4OMBAnKKVcD0sx0oIvOAJFXd2NsLOgE6QO4MZOX9aH0Fkj4WSR3V8U/SVIMe32x2bgAbf23d361N9v3+F5B5/4Bu/19whSOLPmEX1DWfNa/bNq81m7W3Wr11w6+t3to1ZXZ8M/rC9+zrsStgzFIL/C43euIt23XkTD134Pa1BmvkAIWLrE7ua0WTC5D2ZvTpr9mCYvQSJGtSRwOJ7n4aueE7VutK7LRTdodbk8uzD6JjrkUzJ+FKzrVO6jl32oo9Mcfev+zJkJiF1J6y4AzQVGPZhvw51jQWm2qWku2tsOm3tsN3xCiGFZKcB2sftOzJqz+GuhLY+QRauBBZfDfijjAFui49T6pqLnOBkapnH7Agc/NDpqnvSUbc4WhLg2Wu/BKz+vy34dYfdrs+tL0VkJCUsvrazzqiJeFRtgjPmwm40LBIpOYUmpDV4VynJ94KZgdqTkJtCcSPQL0N6OENcHi9iRNFxIA/q6SeVCQhG20ot36MtKLQe0BMkomQ+HUamH4bbH8ETu82Y5+00eZG1fV8G6rQQINYu9c2GrkzTKQpIua8jX2uSC6si7seCKyAYumYEwxFRJKBHwO3nOsJnQDtRyJj4Sw6z1p+qPswf2uTXQQntlr9rLUZFn8aScy2iwL/jvjgKybUkDkBFnwMXvkRMm4ZHN1gwh3+i1RV0T3P2XMn50NULPrXe00O9NibHS5bOn6NeVT3cHPR9lYoO4BWHDKlpi0PWzNXUw368kN20NRb0eoTwd3+ia1oZ+MP9UF9pQXoqHiYcrONluXPQzf9FhoqrOln0Sfxeettl+EfHdFxK2DOh2xXvP8l65rtrBucVmSduVv/ZA5kcz5oixX1haRCHYYPkpwHNafQupLgD8sPmvez+yw1XfWZbWyAdq+5MnULND5bjHZ82xZSQ9SWBqg4ZGn0iBhrXIxKNAngkneslj1ueY+ZG4n0oEn5Fvg2/x51hyMrvmga8gCZExFXGIrCnueCnvBlB2D9T+zrkj3orDvs69GLYeRs9JUfWDAHZPm9tmANvGZUvN0jxq+yLFx7G1q8AwoXoBt/DZg9pC97KhIZ26mLXa1E0OY3oPGkwFsPo1XHYOHHQktSZ0Fbm+H0O5ZFy5xo45/n2bsydDnnDvpcbMXS2huBKcC+rgeISATwKHCvqh471xM6AboT2tps4wwtDWhyvn1AwyKt2SSlAC3bb81M41babrBoqX2YtR3d8bilhhd/quP5pOpo0Mqt9jSSNgbm3GmBrqUecqZbKi0pB4mMQ3Om2Xxk7gzY9Vd7jshYtJMFJiW7LLj6FwEhVBxCn7rfOqQRZNVX0OgEeOLzwWOKt5lMYIC2FmTEeDQ8yhYZCdlouxdO7bLRjf0vWg3w1K5OdTm1elzxtmBWAawbfvxqey+89baCn3UHenA9JOda3fkNf8mmrsw63JNGQvYk+9theBKdZAtN/2eaKbdAL/ra4nLDtHej5QfsMzlhLVpXaiN2flR9Nhp09SfMSrHdiyy5B42Ms7nplnqb+93wqw5pXz081nbxB1+B1EIkdwaUvGMyvj3RUA6b/WYt7a3opt+bZ3lrC+x9zlTPIjzI8s/bohpCxVfaveamF5eBZE81857a4EJFj25E8ufYtENzrWXIPMloTCIiLnyl+2HW7fDSQ4FH2L1j7HLLzM16v6W7PanI3A+jh9fbe114Nbz1sN0Ptv+vjY6ei7J96LPfsFe5UhX6LtwP+nFgvYhkAauA94jIA6p6f6djPoKlvu8TkfuAn6vq/5ztCZ0A3Zljm9CXHrLace50Wz0nZFsNrLHKZD2j4m3XnDzSgmlCFvrmH+3xk64Pfb4eZuo0aaRZ6yXlmfDJk/ehOVNhwUchb5YJmoRFWyqrphitPGoCDcc32xNMWNuxQ+94Tl8bVBdDzalOHzA1M4L0MWjebDjymv04foSpGLVYvUvyZqE1p5FlX7A51aoj8PIPUZcbWfVVS5cVb0Ou/Vf02AbbFY9agLa12k45d3rw3AoX2wq0pc7SdVEJNtoxcS1kTvIrSPm1tcGMEK79nEk3DoDfsMPgRCKiYdq7bbTIHW79FeeaYIiKhyX/jHjr0doypK0JbW+zGd+Dr9pisGipNSHe/JA1cm57xIQ45t9lI0e1p6yJMXAe4ZFooCO6/IAtiL0NZx/Xcvt1+ANBN6BbUHMYApKk/pS2K8tf+04thORR1tAWn2mZorUPmnJhXYn9Xn5tBcmaZOpiL//AFgoT16ExSXZ/GXONlYKObYbYFKj2/x6eVCtfHXzF0uGxqUhcmqnxxY9ABPTwG3YeGeOgobKjHt4bWtepV0l9oSWyKwa9oACtqrUisgRYDnxXVUuAt7sc83Pg5319TidA+1FVs50EC1pb/EG3udZWyuWH7EM7bqUFpOZaC1bXfNYCUGIuMnJ26HOmFthu9dRO+zs+A7b9jzWQ5c1GyvebDObuZ+DENluxh3vgnT9aQNz3nAW4CWuQCWusHp1itXH1NllAdoWhTWfgma8hsz8QFEIJpLzOFEPBAiTzKlMTShlleuJl+yAiBt3yJ2TJp62j+sgbsNefZm9vt5GOlV9Ejm22G9ukm5CUUWh0AtJSa3W4q65DZr3fbkYjxoO40KQ8+32PbUI3/QZiUpBVX0Ij45H5/2DWnXHpSGIW1Jb0kLp0GG5IVJyVefqIhkfBjv9DS/fa94m5SO4sKN0HG39tP2uuReJHWFBb/1NbMIIZtqz+qgW3qbdaGcYd1q1+K9EJqLcFLT9oddryg3ZdJ+dbqSouA677st0L/LP84g5DI6LtugyMjMVn2Ehj6V4zf5l6CxqfiUTHd9TDNTwayg4gU99lI1FJuagrHCndY8EZcxHTN39nx5/ehay4Hz3wopWrTu0ClxvJnY6u99/fOwUTScyC9hb0z58LntfkG5EZ7ztncAaQlIJgFi068cr1hL6wFDeqWk2wk/uCcQK0HxExCdCT2+nY4QVQtTRRfZmlj7f80Y4Jj7KuycLFkFrQURdWXztUHkFa6tGc6ci4lWhcBrr9UUtNxyTD7r+hJ7bY4+fcaSv97Y+ZR3XeTPTUDlyL7+7xXLW9FS3eDqW7ob4MKViEZk5Atz+GTL3FbC2jE9H1P7fZxw2/st8oPBq58XuQloss+pTVteNH2Lm3t1mNbP+LVstLGok2VlojT9ZES1d7kiBlFK7oeBsbWfctyywkZJuCWoDZH7ARrcOv2/eNleiBV2zXMmqe6Y8316Jv/gFZ9y0bk6krNa/upJyB/pJNpfgAABRESURBVK91GIKIOyIkHUztaQtAASe6xBykcBF67E0rnWSM7QjQJtUb01FekSWfNgMbTxpMuw32PQcjJljpaOdfUE8KMvP9Vh8GmxNe8w0kLh3JGIsuvtvS2gFzm6SRyMr70J1/Nb/sggUmhfvUl63cBciKL4ak5CXSA1NuhKZa08v+m78DfO6HA79wsOk0QLsX8mah7zyNTFoHcelofaXJm+bOMtW1zrQ2hc6ZexutB6Av73daIaz7jl3PsWkdEyxXFI6S2OBGChfZReDzWZDZ+jAkZCETVpuJecIIC0zLv2AfZF+bdZF6G5Drv4kmj0Ibq5CmM2hDFWx/FKqOWvpp0g3WFFN93HbogXpcuxc9vcsUfwCqTyCjFtgYVxe0rQVK9qL4rBbt79zUE9uQxZ9CX/w+uvMvMPZavxe2zxYRAVqb7KIVl1ledh71CovAlzoGWfrPcOaEyQvWnDbFs8Rsq1O3t1p9vs3rN7I4y2y1O7y7rGJkrM2TxiRb+ru+HLn2c6YU9ebvYd/z9v6s+grSj52WwzAlKh5mvA9e84+NzrwdohKsZBOXYeJBYRGw9w1zuMqeBhPWwu6/2eLTk2o74KzJFtDqy5GT29GMMZYaP/EWbPD3Q0Qnoic2B1+7rtS0+ePS0YpD8LevQksdOnK2Gb3EJFlpJ2dasKu7+nhIcNQzxd0yahIWCXFpprngb4rU07vsdzv8hmkHxKbbRiCtCE0psDJU/mz0lZ/Y849dBrf8EIlO6FbqIiHL6umHX7Pa+Njl/XrLJXmkle6uZC5QSWygcQJ0JyQ63uo6LQ3WhDHpBru4O9XLxB1unZvNtTan6Uebai3INFSajV5YpNlPbv6DjSJVHrYLB6yTuZOiFsmj/AEVGL0YTR+DpBeZAEHTGTQsyurJ3gb0+W9ZPa+zQ1C711Ju+fOQ7MlWi1v8GSRnOhoZF3yt/HkQ131Mo+N3a6lBS/cinhTEk4qOW9HhOuVrrIKdf7XRl9xp6PjVSGRct5lMANpa0CMbkJm3o0c2mFrUiPGw+Q9w6FVLNS77VxsbKT+I7nu+4/fQHY87AdrBslFFlplCfVZCCouwheuaB6wJ7NCrdi2B2VOOX2kz9XHpHdkscYfZsa/93JoawUpGebPRwISBz4dkTgpmfGJSICYRwBocA650x96Eies6BHVCUsfxWbbzriu1rFjmxLP/bvlz7NwBqo4j8z+K5s81i9qC+Uh8llnbxqagtaXokY3BwLHv78iENUhEdzVBiU6EBXfBlJsgPKbPdpwOAZwd9NCg+hi8ERSIUQh1wcnw27G5w238SlyIS6xhZMef7d/aWizwjBgPVcetKSzwfHueQZbegx5ab9KWjVVWM15yD9ScQtKKbETkpYdM6CQ+E7n649YkI27Y+Rdk8d2W5m5vhfy5aNpoS1NVHEGu+Rf0he9Yd2hyPlz/TaS91Z6nk9qSnjlpM5wxSdal/vZjcOBlf4JfkKWfQWOSTBu5ZE/wd9v7PJJxFdRXoiPGmeNQ57GvyFjIn2MmB2ljrOkuNh1m3mH1+zHXBrWNw6JCFyt9GAlxuDKQsEjopCzW8fO4NGuMqjgUWoyKiu9ZM9vbYKOOAY5uRKfeal7j9RWmgHfsTWTOh6y5LHtyUHSkszGFuMwFr6dzTcg0Cd+6Uqvh9rYTzZ2BrPmGSdsmj7RAvPkZExY6vdPuN6u/YXXlsddatq10jz02whOaFet6HlHx3ZTGHPqB42Y1FOjSVNFl5liiE9CRc5C137TaWFw6qFrtufM8YlQiTH03EhYOIjYGUVdmspnqs/Tb9v/tGF+S+HR05xPomKXIqR3WyAVmunFqp6XBZr8f3fRbdOvDyJoHoKUWVUHK9lt9POMq6wINpJirjiKNVd0b2GpOoU99KegstfSzSPYU09z22wFqdCJSth+fJxVprg99T9q86Ft/sseufTBkJENcbhi9xBra/PVsifTAtFvRyTeEzlcmZts42I7HzQVs3Mrz+h9zuALJnQaTb7JpiqtWWddzT0R4LCUe6LwuXIRExCLpSWh4dIclpRa/BTnTkQmr7VouP2CNWdf+C3psM1Iwv9fA25tOvtaWoEc3mSRp/hyk86gjdNHWlo4gLKmF6KQbwZNmafoJa5B4Z2d8UVAddHoMToDuieR8mPNB2P4YpBRYE0gXRCSkjqutTVB52ATr9/3d6mWTbkAyOtV5r/+2zf/WlZoyUXxWqOavuGDau5GGChuD6vx64dFoTbGZTsz/KKQXoRUHrUN17DL0Lf8oXdYkmPqu4AMjYyEiFj25A/Ukm9RfRKzNg3Z2ljq9C6qOQvZUdPMfkBnvg/U/s0aamCTzdh452zpj08eY+5T67E/t6W4zkxIe2aNbT1fxAxGx+XEnrd2N/jrfXGmIJ8V6Rdq93d3WOh8XGQvzPmyKeu4w25XXnsb39mMWMJd8Gn3lx/b1hNXWMFp+yIw+tN3mgtc+iIy46rzOU72Nlr4OCPocexNWfLGjfAT+yZG6UijZg0xah8amoXv/DsVvIYULYdqtvf6ODgPEBZhlXAycAN0DEhFtNnWFV1vnc0+iIF0fEx6NZk6yecIpN0O7D3WHhe7Fo+MtXbXjz5aay5wIcz8Eu560G01EDBKVYEIhJ7dbrfnk2xYQKw/b67S1mEjKyJlw+A1bTARqawCndppt38KPQfHbppX97APW2epJNSGR+jJkzLWhzlLxI2yRcegVex71daiX0VgNZftt0XHdl6x2F6i/i8uR6Lx49Mv55kpERGz88FzHeVJhlPVLaEudzR77rymtOg5rv4m43UHBkfryYN03cC2cZ4Cmtdl24wEqDtrPOgfogLJee5tJkh7fgvoVyfTIG5atyxx/fq/v0EcuWElswOlXgL6SVvTiDjfJvP48JinX3G0qToLLhR5ej8amBrWBvY1wZEPwAad3IQs/hubPha1/Qg+8bCnjZZ9HU0ebzdzE681wYM/TJtMZk2QB8chGKFwIO56A7MkWQCM8tjhoOgOZE3FddR2+Pc9acAbbrbd7Yc8zkD8HWfsgWrLbjDGObLC0WtZkm6/uKqrvCoN9z5uBxi0/sExBaxPit4sMuPU4DBz9db5x6CNt3tAmy/oyxJMc2vAYnxksV7nDg7aY50NUnF3Hfk1uipbatdPDoQG9cG08E/oPLbXn//oOfePClcQGnP7uoJ0VfS+ICL7ibfD2/wV/OGapNWsl5doMdOFCqzuD6fpGxSP1lRacwdLNO/8CK+9Dxq0wH9voBHwRHnPS8jYhs2zkRFMLzVNZfUhakfkwv/oT1NtgUomTbzLxg+AZBptc2lqQnGnWLV51zOYe49LBHQkjxltab+k96PEtSHI+etK/S/e1IarW5fr0D80rF0FWfTmoU+xwXojIL4DOtYIXVfXrvTnfiMhdwF0AeXl9m3m94olOtN3qq37N7DkfCmpp+5HUAlj3TagttevibPXtPiDucDS1AJl5B+AzLfvq49BpRlkrj5iGvicV0sfadRmdaIvtxFxHCveSMMR30M6K/txIYm4wILrCzCjg+W/Z/OTYZciE621+uM0L6UVIVLwF1M6SgqmFSHMtlO6FsEh8KYWw5Y/m5HP1x222+tB6m52eejOuCA++8kM2xhR4jm2PmOBJezsy+wNobal1h7/zpAn3pwVr493mH0cvMkHOtlZkxERrbNvxZxA3suiTdsMq3Wc7bQDUumCdAH1BqOpHu/7sXM43fj/aXwLMnDlzcBXQBinicqOFi5DUQqs5Jub0mP2RlILzCsza2mzXd1QsIi70zEnE2xhUJwTbUQeOrz6BPnm/TYEAsuwLyKi5sO5b1uwZk4LEnZ/1rEM/GUpz0Oezovc/7spd1edMg6s/AeUHTOFopz/BsPVPMHK2iRzkhVqKSnwmrP6a+cbGpsGoeeiL3w/WrSbfBKMW2GjJi99H25rNW7bykNXKkj1IaoGlvwO4wmyX3FhlDWTRSeb9PPtOiM+yBpte0DavyXu+/gs7p1VfNXOCgNVfdGLIokK6qho5XDD9db5x6DsSFtEhmzuQ6JmT6Ib/tHHJmbfjy55s45Iul+ki1Jy0iYpOC2Qaq0NMNrR0DzJqrt0XnI7tS4gOrSax81nR+x93xa7qJSYRGbfchAf+9uVgo1VSbq/NLJI22oQ7sKYV7dxUcuxNuO4r1jQSGOHa9wIs+QzUleHb9HvrJp90gzn3NFQgk240E4+pt8L41abJrT547kFIzEWv+efebejqSuG1nwe/DnhY+3cakpQDa75hN5PY9OBsuMNA0i/nG4f+oU01gJrAx0A95ztPdTRt6ksPmZRt1VFTHaw8YnoI098T6gMdm2r9Lg2VgCA5UwfsfBz6gTK0U9zOir7vSFQcLL3HjDDcYci4lX3qBtf6crR4mwmclOy2HxYtQeJSg77NYVGm3+1rRZ//gaVlit+y8akxy+DgizZCVb4PXv8PWPQpJHNih50cVUfQ/S8hcz5w9hNxuYNCLGD18y4ORJJaYLU6h4tCf51vHPqOluw25zpVWHrPwI35hehpK4jAtFtNNri91fQBOnVvA6Y7sPpr5kgXkwAp3cVZHC4FQ19JzFnR9wNJykMW3NW/B53eDZt+A5NuQLKnQEKOKRuJC6bcbAIKKaPQtx5Gxq8OrZnUnkYKFqBVhy2gRidAYyU88zVYeX/o65yr4zo+E1l+r6XropOQ2XeGqoU5OAxRtLEaffHfOzQI9IXvwU3fR0LEQs4PmbTORIUaKmHm+yAxD0nIgawpFqyTRvZc707MubBOcYeBYSjVoLvirOgvBf6KwM4nrGFk5f0dggaSkAWL7zZpwo3/hdaXQ/ZUm5mO8CBFS21cZMZ7zQM2Y5yNX7U2oodet/rzzschKR8pWtzrWYiIGQKkfxdcYUgv8oIODkOOzuM06qObgx1+j+SyAxAWDmljkJhzp8IlZRTc8G/Q3gIxiUiY/7o53xlqh0uH42blcE5GXAW5M+HU2zB6qRmvd0KrjpnK2JRb4O3HYPQSZOV9ZvnYSYdYREzG8PVfmHzdyDnW1LXifogbgUTHdX3lHpGAxR6YPGnA2D0u3Xb1Dg5DDIlJsvLTCybxKdd8tlvTpDbXoet/akJBAJNvNNcpbwN4m2w8MtLT8/N7knr8ucMQYIjPQTtcZCQuA5be4/e0jTVVMz9avB3+/l0LuFd/Aln2BRMtScpBXD38V7rCTOQkKcckP1/7GSAmbTh6cZ+M3DteWxWObUZf+Dc7z2X/iubN6tdzODgMFiRrEtz8EKA9TzS01AeDM8CRDeiYa60ju/KwWVbO/oAFe4fhwyAL0M4WaBAikR4kNi00ODfXoq//hwXudi+s/ynaWAnJeT0HZ7B098r7kFHzYf8LgWdCtz0aMtbRJxqrTdjB12Ydqa/8OKjl7eAwBBFP8tnHDSNjQ4V3ChaYJaxfHpQDLwUtYh2GB4EU99n+XAacHfRQQVym8hXAHQ4JWedMM0vaaHxRieB5LGjMkTzKzO77g8ttjWcBb9yIGNuhOzgMQyQqzkSByg7YtZZeBCfeCq1UO9K2w49BtoN27rBDBImMhcWfsl1suxeZ+xHooziIKy4Vve5+dM9zEBVnzWTu/gVoiU6Aaz5nNW1AFn4sxFvawWG4IbFpJtLjR7MmwdjlcGonXLXyguQ/HQYjTpOYwwUgaaNh7YPW2BLVtyavjscm5/d/5Kvrc6QXwVqbpZauZhoODsMciU2D+XdBW5NNTThjh8MLxQnQDhfG2TpHL9nrO4HZ4QpGwsJt7MpheOKkuB0cHBwcHAYbg8/NyunidnBwcHBwUKyT+2x/+oCI/FpENojI/RdyTAAnQDs4ODg4OKAm9Xm2P+dARG4G3Ko6DygQkaLzOaYzToB2cHBwcHCAC52DXgI84v/6OWDheR7TwUWvQW/durVCRC6281UqUHGRX2Own8Plfv0r8RxGXqLX6RMX8VobDP+v4JxHV66k87jo19rWY2eedf/j46m9HBIlIls6ff9Lv7VyAA9w0v91FWYs1ZW+HNPBRQ/Qqpp27qMuDBHZoqozL/brDOZzuNyv75zD5ediXWuD5T11zsM5j4uJql53gU9RDwTGXGLpOUPdl2M6cFLcDg4ODg4OF85WginrKcDR8zymA2fMysHBwcHB4cJ5HFgvIlnAKuA9IvKAqt7fyzFze3vC4bKD/uW5D7noXO5zuNyvD845DFcGy3vqnEcoznkMIlS1FmsC2wgsVdW3uwTnno6p6e05Rfs43+Xg4ODg4OBw6RguO2gHBwcHB4dhxZAP0CKSICJPi8hzIvJnEemnj+KAnUeGiKy/HK89WLic78Fg+RwMNwbT++pcY0EGw3sxmD4bw5UhH6CB24F/V9UVQAlwoa3y/UZEkoDfYTNul5z+SMddxHO4rO8Bg+BzMEwZFO/rIPh8Bc7DudaCDIrPxnBmyAdoVf2Zqj7v/zYNKLsMp9EO3AbUXuoX7q903EXksr0HMGg+B8OOQfS+XtbPFzjXWlcG0Wdj2DLkxqxE5BfA2E4/elFVvy4i84AkVd14Gc/hYr90Tyyhu3TcgUt9Ev7uRC7Te9DBpfwcDEcGw/V1jvO4FC9/NpbgXGvdcK65i8eQC9Cq+tGuPxORZODHwC2X6xwuI/2SjhvOXOrPwXBkMFxfZzuPQYBzrXXBueYuLkM+xe1vTHgUuFdVL7bm92CkX9JxwxXnc3BxcN7XEJxrrRPOZ+PiMxw+YB/BVrL3icjLInLb5T6hS0y/pOOGMVf65+Bi4byvQZxrLRTns3GRcYRKhjgiEg+sB17ALx13LnUaBweH/uNcaw6XGidADwP8YxfLgVdVteRyn4+Dw3DFudYcLiVOgHZwcHBwcBiEDIcatIODg4ODw7DDCdAODg4ODg6DECdAOzg4ODg4DEKcAO3g4ODg4DAIcQK0g4ODg4PDIOT/A3Q69qtWA8RgAAAAAElFTkSuQmCC", "text/plain": [ "

" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize = (9,3))\n", "#自定义cmap\n", "top = cm.get_cmap('Oranges_r', 512)\n", "bottom = cm.get_cmap('Blues', 512)\n", "newcolors = np.vstack((top(np.linspace(0.55, 1, 512)),\n", " bottom(np.linspace(0, 0.75, 512))))\n", "cm_bright = ListedColormap(newcolors, name='OrangeBlue')\n", "plt.subplot(121)\n", "m1 = plt.scatter(*X.T,c = y,cmap = cm_bright,edgecolors='white',s = 20,linewidths = 0.5)\n", "plt.title('train samples')\n", "plt.axis('equal')\n", "plt.subplot(122)\n", "m2 = plt.scatter(*X_test.T,c = y_test,cmap = cm_bright,edgecolors='white',s = 20,linewidths = 0.5);\n", "plt.title('test samples')\n", "plt.axis('equal')\n", "ax = fig.get_axes()\n", "plt.colorbar(ax = ax);\n", "plt.show();\n", "\n", "prob = np.squeeze(net.predict_pro(p))\n", "p1 = np.array([np.squeeze(pp) for pp in p])\n", "fig, (ax1,ax2) = plt.subplots(1,2, figsize=(9, 3),subplot_kw = {'aspect':'equal'})\n", "ax1.scatter(*p1.T,c = prob,cmap = cm_bright)\n", "ax1.scatter(*X.T,c = y,cmap = cm_bright,edgecolors='white',s = 20,linewidths = 0.5)\n", "ax1.set_title('train score:%.5f'%net.accuracy(training_data,convert=True))\n", "mp = ax2.scatter(*p1.T,c = prob,cmap = cm_bright)\n", "ax2.scatter(*X_test.T,c = y_test,cmap = cm_bright,edgecolors='white',s = 20,linewidths = 0.5)\n", "ax2.set_title('test score:%.5f'%net.accuracy(test_data,convert=True));\n", "plt.colorbar(mp,ax = [ax1,ax2]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7.6.5 定义逐层可视化函数" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def scatter(p, c, X, wb=None, cmap='Set3', value=True, zero_start=True):\n", " global y\n", " cols = p.shape[-1]\n", " # assert cols in (1,2,3)\n", " fig = plt.figure(figsize=(6, 4))\n", " c_u = np.unique(c)\n", "\n", " if cols > 3:\n", " ax = plt.gca()\n", " ax.axis('equal')\n", " if wb is not None:\n", " a1, a2 = p.min(0)[:2] - 0.2\n", " b1, b2 = p.max(0)[:2] + 0.2\n", " (u1, u2, *_), b_ = wb\n", " y1, y2 = (a1 * u1 + b_) / (-u2), (b1 * u1 + b_) / (-u2)\n", " ax.plot([a1, b1], [y1, y2], 'k--')\n", " ax.set_ylim(a2, b2)\n", "\n", " st = ax.scatter(*p[:, :2].T, c=c, cmap=cmap)\n", " ax.scatter(*X[:, :2].T, c=y, alpha=0.7, cmap=cm_bright, edgecolors='white', s=20, linewidths=0.5)\n", " if value:\n", " fig.colorbar(st,shrink=0.8)\n", " else:\n", " if zero_start:\n", " fig.colorbar(st, ticks=np.linspace(0, c_u.shape[0] - 1, c_u.shape[0]),shrink=0.8)\n", " else:\n", " fig.colorbar(st, ticks=c_u,shrink=0.8)\n", "\n", " ax.set_xlabel('X')\n", " ax.set_ylabel('Y')\n", "\n", " return ax\n", "\n", "\n", " elif cols == 3:\n", " ax3d = Axes3D(fig)\n", " if wb is not None:\n", " (u1, u2, u3), b_ = wb\n", " a1, a2, a3 = p.min(0)[:3]\n", " b1, b2, b3 = p.max(0)[:3]\n", " if u3!=0:\n", " a, b = np.mgrid[a1 - 1:b1:10j, a2 - 1:b2:10j]\n", " z_ = (a * u1 + b * u2 + b_) / (-u3)\n", " else:\n", " if np.abs(u1)>np.abs(u2):\n", " b, z_ = np.mgrid[a2-1:b2:10j,a3-1:b3:10j]\n", " a = (b*u2+b_)/(-u1)\n", " else:\n", " a,z_ = np.mgrid[a1-1:b1:10j,a3-1:b3:10j]\n", " b = (a*u1+b_)/(-u2)\n", " wf = ax3d.plot_wireframe(a, b, z_)\n", " wf.set_color('k')\n", "\n", " mp = ax3d.scatter(*(p.T), c=c, cmap=cmap)\n", " ax3d.scatter(*X.T, c=y, cmap=cm_bright, edgecolors='white', s=40, linewidths=0.5)\n", "\n", " if value:\n", " fig.colorbar(mp, shrink=0.8)\n", " else:\n", " if zero_start:\n", " fig.colorbar(mp, shrink=0.8, ticks=np.linspace(0, c_u.shape[0] - 1, c_u.shape[0]))\n", " else:\n", " fig.colorbar(mp, ticks=c_u,shrink=0.8)\n", "\n", " ax3d.set_xlabel('X')\n", " ax3d.set_ylabel('Y')\n", " ax3d.set_zlabel('Z')\n", " return ax3d\n", "\n", " elif cols == 2:\n", " ax = plt.gca()\n", " ax.axis('equal')\n", " if wb is not None:\n", " a1, a2 = p.min(0) - 0.2\n", " b1, b2 = p.max(0) + 0.2\n", " (u1, u2), b_ = wb\n", " y1, y2 = (a1 * u1 + b_) / (-u2), (b1 * u1 + b_) / (-u2)\n", " ax.plot([a1, b1], [y1, y2], 'r--')\n", " ax.set_ylim(a2, b2)\n", "\n", " st = ax.scatter(*p.T, c=c, cmap=cmap)\n", " ax.scatter(*X.T, c=y, alpha=0.7, cmap=cm_bright, edgecolors='white', s=20, linewidths=0.5)\n", " if value:\n", " fig.colorbar(st,shrink=0.8)\n", " else:\n", " if zero_start:\n", " fig.colorbar(st, ticks=np.linspace(0, c_u.shape[0] - 1, c_u.shape[0]),shrink=0.8)\n", " else:\n", " fig.colorbar(st, ticks=c_u,shrink=0.8)\n", "\n", " ax.set_xlabel('X')\n", " ax.set_ylabel('Y')\n", "\n", "\n", " else:\n", " ax = plt.gca()\n", " t, tt = np.zeros_like(p.flat), np.zeros_like(X.flat)\n", " st = plt.scatter(p.flat, t, c=c, cmap=cmap)\n", " ax.scatter(X.flat, tt, c=y, alpha=0.7, cmap=cm_bright, edgecolors='white', s=20, linewidths=0.5)\n", " if value:\n", " fig.colorbar(st,shrink=0.8)\n", " else:\n", " if zero_start:\n", " fig.colorbar(st, ticks=np.linspace(0, c_u.shape[0] - 1, c_u.shape[0]),shrink=0.8)\n", " else:\n", " fig.colorbar(st, ticks=c_u,shrink=0.8)\n", " return ax\n", "\n", "def add_hyperplane(ax,p,wb,color='gray'):\n", " #添加超平面\n", " cols = p.shape[-1]\n", " assert cols in [2,3]\n", " if cols==3:\n", " a1, a2 = p.min(0)[:2]\n", " b1, b2 = p.max(0)[:2]\n", " a, b = np.mgrid[a1 - 1:b1:10j, a2 - 1:b2:10j]\n", " (u1, u2, u3), b_ = wb\n", " z_ = (a * u1 + b * u2 + b_) / (-u3)\n", " ax.plot_wireframe(a,b,z_,color=color)\n", " else:\n", " a1, a2 = p.min(0) - 0.2\n", " b1, b2 = p.max(0) + 0.2\n", " (u1, u2), b_ = wb\n", " y1, y2 = (a1 * u1 + b_) / (-u2), (b1 * u1 + b_) / (-u2)\n", " ax.plot([a1, b1], [y1, y2], color=color)\n", " return ax\n", "\n", "def mapping(code):\n", " # 转化为01编码的类型\n", " numMap = np.zeros(code.shape[0])\n", " uniq = np.unique(code, axis=0)\n", " for i, arr in enumerate(uniq):\n", " m = (np.sum(code == arr, axis=1) == code.shape[-1])\n", " numMap[m] = i\n", " return numMap\n", "\n", "color_list = ['aquamarine', 'b', 'blueviolet','c', 'chartreuse',\n", " 'darkcyan', 'darkgreen', 'darkkhaki', 'deeppink', 'deepskyblue',\n", " 'gold', 'indigo', 'lightcoral', 'maroon', 'navy', 'olivedrab', 'peru',\n", " 'pink', 'rosybrown', 'saddlebrown', 'slategray', 'steelblue', 'teal',\n", " 'thistle', 'violet', 'y', 'yellow']\n", "cmap = colors.ListedColormap(color_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7.6.6 卷积网络分类过程逐层可视化" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": false }, "outputs": [ { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "D:\\anaconda\\lib\\site-packages\\ipykernel_launcher.py:5: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n", " \"\"\"\n" ] }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('');\n button.click(method_name, toolbar_event);\n button.mouseover(tooltip, toolbar_mouse_event);\n nav_element.append(button);\n }\n\n // Add the status bar.\n var status_bar = $('');\n nav_element.append(status_bar);\n this.message = status_bar[0];\n\n // Add the close button to the window.\n var buttongrp = $('
');\n var button = $('');\n button.click(function (evt) { fig.handle_close(fig, {}); } );\n button.mouseover('Stop Interaction', toolbar_mouse_event);\n buttongrp.append(button);\n var titlebar = this.root.find($('.ui-dialog-titlebar'));\n titlebar.prepend(buttongrp);\n}\n\nmpl.figure.prototype._root_extra_style = function(el){\n var fig = this\n el.on(\"remove\", function(){\n\tfig.close_ws(fig, {});\n });\n}\n\nmpl.figure.prototype._canvas_extra_style = function(el){\n // this is important to make the div 'focusable\n el.attr('tabindex', 0)\n // reach out to IPython and tell the keyboard manager to turn it's self\n // off when our div gets focus\n\n // location in version 3\n if (IPython.notebook.keyboard_manager) {\n IPython.notebook.keyboard_manager.register_events(el);\n }\n else {\n // location in version 2\n IPython.keyboard_manager.register_events(el);\n }\n\n}\n\nmpl.figure.prototype._key_event_extra = function(event, name) {\n var manager = IPython.notebook.keyboard_manager;\n if (!manager)\n manager = IPython.keyboard_manager;\n\n // Check for shift+enter\n if (event.shiftKey && event.which == 13) {\n this.canvas_div.blur();\n event.shiftKey = false;\n // Send a \"J\" for go to next cell\n event.which = 74;\n event.keyCode = 74;\n manager.command_mode();\n manager.handle_keydown(event);\n }\n}\n\nmpl.figure.prototype.handle_save = function(fig, msg) {\n fig.ondownload(fig, null);\n}\n\n\nmpl.find_output_cell = function(html_output) {\n // Return the cell and output element which can be found *uniquely* in the notebook.\n // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n // IPython event is triggered only after the cells have been serialised, which for\n // our purposes (turning an active figure into a static one), is too late.\n var cells = IPython.notebook.get_cells();\n var ncells = cells.length;\n for (var i=0; i= 3 moved mimebundle to data attribute of output\n data = data.data;\n }\n if (data['text/html'] == html_output) {\n return [cell, data, j];\n }\n }\n }\n }\n}\n\n// Register the function which deals with the matplotlib target/channel.\n// The kernel may be null if the page has been refreshed.\nif (IPython.notebook.kernel != null) {\n IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n}\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "/* Put everything inside the global mpl namespace */\nwindow.mpl = {};\n\n\nmpl.get_websocket_type = function() {\n if (typeof(WebSocket) !== 'undefined') {\n return WebSocket;\n } else if (typeof(MozWebSocket) !== 'undefined') {\n return MozWebSocket;\n } else {\n alert('Your browser does not have WebSocket support. ' +\n 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n 'Firefox 4 and 5 are also supported but you ' +\n 'have to enable WebSockets in about:config.');\n };\n}\n\nmpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n this.id = figure_id;\n\n this.ws = websocket;\n\n this.supports_binary = (this.ws.binaryType != undefined);\n\n if (!this.supports_binary) {\n var warnings = document.getElementById(\"mpl-warnings\");\n if (warnings) {\n warnings.style.display = 'block';\n warnings.textContent = (\n \"This browser does not support binary websocket messages. \" +\n \"Performance may be slow.\");\n }\n }\n\n this.imageObj = new Image();\n\n this.context = undefined;\n this.message = undefined;\n this.canvas = undefined;\n this.rubberband_canvas = undefined;\n this.rubberband_context = undefined;\n this.format_dropdown = undefined;\n\n this.image_mode = 'full';\n\n this.root = $('
');\n this._root_extra_style(this.root)\n this.root.attr('style', 'display: inline-block');\n\n $(parent_element).append(this.root);\n\n this._init_header(this);\n this._init_canvas(this);\n this._init_toolbar(this);\n\n var fig = this;\n\n this.waiting = false;\n\n this.ws.onopen = function () {\n fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n fig.send_message(\"send_image_mode\", {});\n if (mpl.ratio != 1) {\n fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n }\n fig.send_message(\"refresh\", {});\n }\n\n this.imageObj.onload = function() {\n if (fig.image_mode == 'full') {\n // Full images could contain transparency (where diff images\n // almost always do), so we need to clear the canvas so that\n // there is no ghosting.\n fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n }\n fig.context.drawImage(fig.imageObj, 0, 0);\n };\n\n this.imageObj.onunload = function() {\n fig.ws.close();\n }\n\n this.ws.onmessage = this._make_on_message_function(this);\n\n this.ondownload = ondownload;\n}\n\nmpl.figure.prototype._init_header = function() {\n var titlebar = $(\n '
');\n var titletext = $(\n '
');\n titlebar.append(titletext)\n this.root.append(titlebar);\n this.header = titletext[0];\n}\n\n\n\nmpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n\n}\n\n\nmpl.figure.prototype._root_extra_style = function(canvas_div) {\n\n}\n\nmpl.figure.prototype._init_canvas = function() {\n var fig = this;\n\n var canvas_div = $('
');\n\n canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n\n function canvas_keyboard_event(event) {\n return fig.key_event(event, event['data']);\n }\n\n canvas_div.keydown('key_press', canvas_keyboard_event);\n canvas_div.keyup('key_release', canvas_keyboard_event);\n this.canvas_div = canvas_div\n this._canvas_extra_style(canvas_div)\n this.root.append(canvas_div);\n\n var canvas = $('');\n canvas.addClass('mpl-canvas');\n canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n\n this.canvas = canvas[0];\n this.context = canvas[0].getContext(\"2d\");\n\n var backingStore = this.context.backingStorePixelRatio ||\n\tthis.context.webkitBackingStorePixelRatio ||\n\tthis.context.mozBackingStorePixelRatio ||\n\tthis.context.msBackingStorePixelRatio ||\n\tthis.context.oBackingStorePixelRatio ||\n\tthis.context.backingStorePixelRatio || 1;\n\n mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n\n var rubberband = $('');\n rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n\n var pass_mouse_events = true;\n\n canvas_div.resizable({\n start: function(event, ui) {\n pass_mouse_events = false;\n },\n resize: function(event, ui) {\n fig.request_resize(ui.size.width, ui.size.height);\n },\n stop: function(event, ui) {\n pass_mouse_events = true;\n fig.request_resize(ui.size.width, ui.size.height);\n },\n });\n\n function mouse_event_fn(event) {\n if (pass_mouse_events)\n return fig.mouse_event(event, event['data']);\n }\n\n rubberband.mousedown('button_press', mouse_event_fn);\n rubberband.mouseup('button_release', mouse_event_fn);\n // Throttle sequential mouse events to 1 every 20ms.\n rubberband.mousemove('motion_notify', mouse_event_fn);\n\n rubberband.mouseenter('figure_enter', mouse_event_fn);\n rubberband.mouseleave('figure_leave', mouse_event_fn);\n\n canvas_div.on(\"wheel\", function (event) {\n event = event.originalEvent;\n event['data'] = 'scroll'\n if (event.deltaY < 0) {\n event.step = 1;\n } else {\n event.step = -1;\n }\n mouse_event_fn(event);\n });\n\n canvas_div.append(canvas);\n canvas_div.append(rubberband);\n\n this.rubberband = rubberband;\n this.rubberband_canvas = rubberband[0];\n this.rubberband_context = rubberband[0].getContext(\"2d\");\n this.rubberband_context.strokeStyle = \"#000000\";\n\n this._resize_canvas = function(width, height) {\n // Keep the size of the canvas, canvas container, and rubber band\n // canvas in synch.\n canvas_div.css('width', width)\n canvas_div.css('height', height)\n\n canvas.attr('width', width * mpl.ratio);\n canvas.attr('height', height * mpl.ratio);\n canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n\n rubberband.attr('width', width);\n rubberband.attr('height', height);\n }\n\n // Set the figure to an initial 600x600px, this will subsequently be updated\n // upon first draw.\n this._resize_canvas(600, 600);\n\n // Disable right mouse context menu.\n $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n return false;\n });\n\n function set_focus () {\n canvas.focus();\n canvas_div.focus();\n }\n\n window.setTimeout(set_focus, 100);\n}\n\nmpl.figure.prototype._init_toolbar = function() {\n var fig = this;\n\n var nav_element = $('
');\n nav_element.attr('style', 'width: 100%');\n this.root.append(nav_element);\n\n // Define a callback function for later on.\n function toolbar_event(event) {\n return fig.toolbar_button_onclick(event['data']);\n }\n function toolbar_mouse_event(event) {\n return fig.toolbar_button_onmouseover(event['data']);\n }\n\n for(var toolbar_ind in mpl.toolbar_items) {\n var name = mpl.toolbar_items[toolbar_ind][0];\n var tooltip = mpl.toolbar_items[toolbar_ind][1];\n var image = mpl.toolbar_items[toolbar_ind][2];\n var method_name = mpl.toolbar_items[toolbar_ind][3];\n\n if (!name) {\n // put a spacer in here.\n continue;\n }\n var button = $('